/* Rage Light Editor */ --fileins filein (RsConfigGetWildWestDir() + "script/3dsMax/_config_files/Wildwest_header.ms") filein (RsConfigGetWildWestDir() + "script/3dsMax/_common_functions/LightPresetCore.ms") --structs struct RageGridCell ( columnName, attr, attrType, gtaAttrIdx, value ) struct RageLightEditor ( __DEBUG__ = true, rageLights = for l in $lights where classOf l == RageLight collect (DataPair name:l handle:l.handle), rageLightProps = #(), lightPhotoAttrNames = for i = 1 to getNumAttr "Gta LightPhoto" collect getAttrName "Gta LightPhoto" i, columns = #("Name", "Enabled", "Preset", "Type", "Colour", "Intensity", "Falloff", "Show Attenuation"), timeCycleColumns = #("Name", "Enabled", "Preset", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", \ "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", \ "Is time object", "Allow Vanish Whilst Viewed" ), lightPhotoColumns = #("Name", "Enabled", "Preset"), UIColumnExclusion = #("Day", "Night", "Calc From Exterior Ambient", "Attach"), activePropertyFilter = "Standard", activePropertyColumnFilter = columns, standard_UI_property_Map = #( DataPair ui:"Name" property:"Name", DataPair ui:"Enabled" property:"lightEnabled", DataPair ui:"Preset" property:"Preset", DataPair ui:"Type" property:"lightType", DataPair ui:"Colour" property:"lightColour", DataPair ui:"Intensity" property:"lightIntensity", DataPair ui:"Falloff" property:"lightExpFalloff", DataPair ui:"Atten End" property:"lightAttenEnd", DataPair ui:"Width Atten End" property:"lightWidthAttenEnd", DataPair ui:"HotSpot" property:"lightHotspot", DataPair ui:"Radial Falloff" property:"lightFalloff", DataPair ui:"Square" property:"lightIsSquare", DataPair ui:"Shadow Map" property:"lightShadowMap", DataPair ui:"Show Attenuation" property:"lightAttenShow" ), --This mapping is define for each column name a type by which the datagridview column type is defined UIColumn_Type_Map = #( DataPair column:"Name" type:"editbox", DataPair column:"Enabled" type:"checkbox", DataPair column:"Preset" type:"combobox", DataPair column:"Type" type:"combobox", DataPair column:"Colour" type:"Image", DataPair column:"Intensity" type:"spinner", DataPair column:"Falloff" type:"spinner", DataPair column:"Atten End" type:"spinner", DataPair column:"Width Atten End" type:"spinner", DataPair column:"HotSpot" type:"spinner", DataPair column:"Radial Falloff" type:"spinner", DataPair column:"Square" type:"checkbox", DataPair column:"Shadow Map" type:"Image", DataPair column:"Show Attenuation" type:"checkbox" ), --store the gta light attrs and control types gtaLightAttrs_MapDict = dotNetObject "RSG.MaxUtils.MaxDictionary", standard_UI_property_MapDict = dotNetObject "RSG.MaxUtils.MaxDictionary", UIColumn_Type_MapDict = dotNetObject "RSG.MaxUtils.MaxDictionary", rageLightTypes = #("Omni", "FreeSpot", "TargetSpot", "FreeDirect", "TargetDirect", "Sausage" ), rageLightPresetNames = #(), multiRowSelection = #(), checkBoxState = false, displayInstances = false, flashOpts = #("Constant", "Random", "Random - On if wet", "One a second", "Two a second", "Five a second", "Random flashiness", \ "Off(Traffic Light)", "UNDEFINED", "Alarm", "On When Raining", "Cycle 1", "Cycle 2", "Cycle 3", "Disco", "Candle", \ "Plane", "Fire"), --UI editorForm = undefined, columnSelectorForm = undefined, formWidth = 800, formHeight = 600, startPos = [200, 120], buttonRowHeight = 34, RSNLogoBmpPath = RsConfigGetToolsDir() + "dcc/current/max2012/ui/usericons/RockStarNorthLogo.bmp", RSNHelpBmpPath = RsConfigGetToolsDir() + "dcc/current/max2012/ui/usericons/HelpIcon_32.bmp", rageGrid, rsBannerPanel = undefined, rsLogo_bmp = (RsConfigGetWildwestDir() +"script/3dsMax/UI/WW_banner_rsLogo.png"), rsMail_bmp = (RsConfigGetWildwestDir() +"script/3dsMax/UI/WW_banner_mail.png"), rsHelp_bmp = (RsConfigGetWildwestDir() +"script/3dsMax/UI/WW_banner_wiki.png"), standardPropsCheckBox = undefined, timeCyclePropsCheckBox = undefined, lightPhotoPropsCheckBox = undefined, --colours rageGridCol_OffWhite = (dotNetClass "System.Drawing.Color").fromARGB 241 241 241, rageGridCol_LightGrey = (dotNetClass "System.Drawing.Color").fromARGB 225 225 225, rageGridCol_BackroundGrey = (dotNetClass "System.Drawing.Color").fromARGB 64 64 64, rageGridCol_Text = (dotNetClass "System.Drawing.Color").fromARGB 80 80 80, rageGridCol_TextSelected = (dotNetClass "System.Drawing.Color").fromARGB 20 20 20, rageGridCol_LightBlue = (dotNetClass "System.Drawing.Color").fromARGB 140 211 246, rageGridCol_Peach = (dotNetClass "System.Drawing.Color").fromARGB 240 172 128, rageGridCol_Empty = (dotNetClass "System.Drawing.Color").Empty, --columns contentAlignMent_midCenter = (dotnetClass "System.Windows.Forms.DataGridViewContentAlignment").MiddleCenter, columnResize_DisplayedCells = (dotnetClass "System.Windows.Forms.DataGridViewAutoSizeColumnMode").DisplayedCells, rageLightDeleted = false, --ON CREATE on create do ( --populate standard_UI_property_Map for entry in standard_UI_property_Map do ( standard_UI_property_MapDict.add entry.ui entry.property ) for entry in UIColumn_Type_Map do ( UIColumn_Type_MapDict.add entry.column entry.type ) --build Gta Light attr dictionary for i = 1 to (GetNumAttr "Gta LightPhoto") do ( attrName = (GetAttrName "Gta LightPhoto" i) gtaLightAttrs_MapDict.add attrName (GetControlType "Gta LightPhoto" attrName) --also add to the column visibility array for these attrs if i > 27 then append lightPhotoColumns (GetAttrName "Gta LightPhoto" i) ) ----------------------------------- --Get presets from xml config ----------------------------------- lightPresetCore.getLightTypePresets() lightPresetCore.getPresetComparatorDict() local UINames = #() --Build dropdown list names --Get enumerator it = lightPresetCore.gLightPresetDict.Keys.GetEnumerator() while it.MoveNext() != false do ( --get name append rageLightPresetNames it.Current ) --Setup callbacks for handling light creation/deletion/name change callbacks.removeScripts id:#RageLightEditor --callbacks.addScript #nodeNameSet "rle.cb_lightRename()" id:#RageLightEditor --callbacks.addScript #sceneNodeAdded "rle.cb_lightAdded()" id:#RageLightEditor --callbacks.addScript #nodePreDelete "rle.cb_lightPreDelete()" id:#RageLightEditor --callbacks.addScript #nodePostDelete "rle.cb_lightPostDelete()" id:#RageLightEditor ), /******************************** FUNCTIONS ********************************/ fn cb_lightRename = ( --#(name, name) changes = callbacks.notificationParam() print changes --rename the entry in the ragegrid ), fn cb_lightAdded = ( newNode = callbacks.notificationParam() if classOf newNode == RageLight then --relist the lights ( print "lightAdded" rle.createUI() ) ), fn cb_lightPreDelete = ( oldNode = callbacks.notificationParam() if classOf oldNode == RageLight then --set the switch ( print "predelete" rageLightDeleted = true ) ), fn cb_lightPostDelete = ( if rageLightDeleted == true then ( print "update list after deelte" rageLightDeleted = false rle.createUI() ) ), fn getCell e = ( --create a Cell struct cell = RageGridCell() dataGridCell = ::rle.rageGrid.columns.item[e.ColumnIndex] cell.columnName = dataGridCell.headerText --based on activePropertyFilter case activePropertyFilter of ( "Standard": ( rle.standard_UI_property_MapDict.TryGetValue cell.columnName &cell.attr rle.UIColumn_Type_MapDict.TryGetValue cell.columnName &cell.attrType cell.value = rle.rageGrid.rows.item[e.RowIndex].cells.item[e.ColumnIndex].value cell.gtaAttrIdx = 0 --non gta light photo attrs ) default: ( cell.attr = cell.columnName rle.gtaLightAttrs_MapDict.TryGetValue cell.columnName &cell.attrType if cell.columnName == "Preset" then cell.attrType = "combobox" cell.value = rle.rageGrid.rows.item[e.RowIndex].cells.item[e.ColumnIndex].value cell.gtaAttrIdx = dataGridCell.tag ) ) cell ), fn createColourSwatch inColour = ( --create graphics object g colour = (dotNetClass "System.Drawing.Color").fromARGB inColour[1] inColour[2] inColour[3] --create bitmap bm = dotnetObject "System.Drawing.Bitmap" 30 30 g = (dotnetClass "System.Drawing.Graphics").FromImage bm g.clear colour --return bm ), --/////////////////////////////////////////////////////////////// --Set the value in the row for the given light --/////////////////////////////////////////////////////////////// fn populateRow row theLightName = ( --format "row: % \n" row if theLightName == undefined then ( theLight = rageLights[idx] theLightName = theLight.name ) --iterate columns gridColumnIt = rageGrid.Columns.GetEnumerator() while gridColumnIt.MoveNext() != false do ( --column name local gridColumnName = gridColumnIt.Current.HeaderText --format "populateRow - gridColumnName: % \n" gridColumnName --match to light prop lightProperty = undefined standard_UI_property_MapDict.TryGetValue gridColumnName &lightProperty --if we get an undefined lightProperty then start looking through the Gta Light attr if lightProperty == undefined then lightProperty = gridColumnName columnIdx = gridColumnIt.Current.Index --format "LightName: % LightProperty: % \n" theLightName lightProperty case lightProperty of ( --"special" cases "Preset": ( --print "Populate Preset:" --columnIdx = findItem columns "Preset" val = getAppData theLightName 1 --format "light: % val: % \n" theLightName val if val != undefined then ( idx = findItem rageLightPresetNames val row.cells.item[columnIdx].value = val ) ) --The usual suspects default: ( --columnIdx = (findItem columns gridColumnName) - 1 --format "light: % \n" rageLights[l+1] columnType = undefined val = undefined if isProperty theLightName lightProperty then --standard type ( UIColumn_Type_MapDict.TryGetValue gridColumnName &columnType val = getProperty theLightName lightProperty ) else -- Gta Light ( --format "lightProperty: % \n" lightProperty attrIdx = GetAttrIndex "Gta LightPhoto" lightProperty columnType = GetControlType "Gta LightPhoto" lightProperty val = getAttr theLightName attrIdx ) --format "columnType: % \n" columnType --valtype case (columnType) of ( "Image": ( --get a bitmap swatch if val != undefined then ( if (classof val) == BitmapTexture then ( bm = createColourSwatch #(255, 255, 255) row.cells.item[columnIdx].value = bm ) else ( bm = createColourSwatch #(val.r, val.g, val.b) row.cells.item[columnIdx].value = bm ) ) ) "BooleanClass": ( --format "Bool Switch\n" row.cells.item[columnIdx].value = val as Boolean ) "combobox": ( case gridColumnName of ( /* "Preset": ( row.cells.item[columnIdx].value = rageLightPresetNames[val] ) */ "Type": ( row.cells.item[columnIdx].value = rageLightTypes[val] ) "Flashiness": ( if val != 0 then ( --format "populate Flashiness: val:% flashOpts:%\n" val flashOpts[val] row.cells.item[columnIdx].value = flashOpts[val+1] ) ) ) ) default: ( try ( row.cells.item[columnIdx].value = val as string )catch() ) ) --columnType ) --default case ) --case lightproperty ) --column iterator ), fn listLights = ( --first clear any entries rageGrid.Rows.Clear() --get rage light properties if we have any rage lights if rageLights.count != 0 then ( rageLightProps = getPropNames rageLights[1].name ) else return false --iterate lights and create rows along the way for l = 0 to rageLights.count - 1 do ( idx = rageGrid.Rows.Add() row = rageGrid.Rows.Item[idx] row.tag = rageLights[l+1].handle populateRow row rageLights[l+1].name ) --lights iteration ), fn changePreset theLight preset row = ( --format "Switching preset to: % \n" preset setAppData theLight 1 preset --do the setting per column select theLight lightPresetCore.applyPreset preset populateRow row theLight ), ----------------------------------------- -- DOTNET UI EVENTS ----------------------------------------- fn Event_editorForm_Resize s e = ( if s.width != rle.formWidth then ( rle.formWidth = s.width ) ), fn Event_RageGrid_updateSelection s e = ( --print "update selection" --clear header cell selection markers if rle.multiRowSelection.count == 0 then ( for r = 0 to s.rows.count - 1 do ( row = s.rows.item[r] rowHeader = row.headerCell.value = "" --rowHeader.value = "" ) ) if s.SelectedRows.count > 1 then ( ::rle.multiRowSelection = s.SelectedRows --format "multiRowSelection.count: % \n" rle.multiRowSelection.count --highlight the header cells for the selected rows to indicate affected selection rowIt = s.SelectedRows.GetEnumerator() while rowIt.MoveNext() != false do ( row = rowIt.Current rowHeader = row.headerCell.value = "*" --rowHeader.value = "*" ) ) else ( --check if this is part of the current mutiselection enclosedSelection = false if rle.multiRowSelection.count > 0 then ( multiRowIt = rle.multiRowSelection.GetEnumerator() while multiRowIt.MoveNext() != false do ( row = multiRowIt.Current if s.SelectedRows.item[0].equals row then enclosedSelection = true ) ) if enclosedSelection == false then ( s.SelectedRows.item[0].headercell.value = "*" ::rle.multiRowSelection = #() ) ) ), fn Event_ColumnSelector_Click s e = ( --print "Column Selector Pressed" --dont filter for timecycle flags if rle.activePropertyFilter == "TimeCycle" then return false rle.createColumnSelectorUI() rle.columnSelectorForm.show() ), fn Event_Combo_Click s e = ( --print "combo click" ), fn Event_ColumnSelector_FormClosed s e = ( --update the columns --rle.columns = #("Name", "Enabled", "Preset") --local switches = #(DataPair name:"Name" value:true, DataPair name:"Enabled" value:true, DataPair name:"Preset" value:true) local switches = dotNetObject "RSG.MaxUtils.MaxDictionary" formControlsIt = s.controls.Item[0].controls.GetEnumerator() while formControlsIt.MoveNext() != false do ( --print formControlsIt.current switches.add formControlsIt.current.text formControlsIt.current.checked ) --format "switches: % \n" switches.count as string --update the main UI columns --iterate the columns columnsIt = rle.rageGrid.Columns.GetEnumerator() while columnsIt.MoveNext() != false do ( --if name is in colums arrray its visible otherwise not if switches.containsKey columnsIt.Current.HeaderText != false then ( columnsIt.Current.visible = switches.item[columnsIt.Current.HeaderText] ) ) --refresh the grid rle.rageGrid.Refresh() ), fn Event_RageGrid_cellClick sender e = ( --format "--------EVENT: cell click----------\n" --show e multiMode = rle.multiRowSelection.count > 0 --format "multiMode: % \n" multiMode --column name if e.ColumnIndex > 0 then ( --get cell data --print e local cell = rle.getCell e local attrType = cell.attrType local cellValue = cell.value local columnName = rle.rageGrid.columns.item[e.ColumnIndex].headerText --format "attrType: %\n" attrType case attrType of ( "Image": ( --print "Image" if columnName == "Colour" then --spawn a colour picker ( --get bitmap colour - cellvalue holds a bitmap here currentColour = cell.value.getPixel 0 0 colourDialog = dotnetObject("System.Windows.Forms.ColorDialog") colourDialog.fullOpen = true colourDialog.color = currentColour colourDialog.showDialog() --on the other side push the chosen colour back to the swatch --so create a new bitmap and assign it to the cell --create bitmap bm = dotnetObject "System.Drawing.Bitmap" 30 30 g = (dotnetClass "System.Drawing.Graphics").FromImage bm g.clear colourDialog.color --update cell --cellValue = bm rle.rageGrid.rows.item[e.RowIndex].cells.item[e.ColumnIndex].value = bm --if multiMode != true then rle.Event_RageGrid_updateCell sender e rle.Event_RageGrid_updateCell sender e ) ) "checkbox": ( --format "checkBox cellValue: % \n" cellValue --if cellValue then cellValue = false else cellValue = true --if multiMode != true then rle.Event_RageGrid_updateCell sender e rle.Event_RageGrid_updateCell sender e ) default: ( --print "Default" rle.rageGrid.BeginEdit true --if multiMode != true then rle.Event_RageGrid_updateCell sender e --rle.Event_RageGrid_updateCell sender e ) ) ) ), --Refresh the table fn Event_RageGrid_refreshGrid s e = ( --return false --update the cells in the rows for r = 0 to (rle.rageGrid.rows.count - 1) do ( theLight = getNodeByName rle.rageGrid.rows.item[r].cells.item[0].value rle.populateRow rle.rageGrid.rows.item[r] theLight ) ), --Solidify the UI values to the object fn Event_RageGrid_updateCell s e = ( --format "--------EVENT: Update Cell----------\n" multiMode = rle.multiRowSelection.count > 0 --format "multiRow count: % \n" rle.multiRowSelection.count --format "s: % e: % \n" s e --format "column: % row: % \n" e.ColumnIndex e.RowIndex theRow = rle.rageGrid.rows.item[e.RowIndex] if e.columnIndex == -1 then return false --do nothing for header cell local columnName = rle.rageGrid.columns.item[e.ColumnIndex].headerText theLights = #() --the lights to update --get the cell data local cell = rle.getCell e local attr = cell.attr local attrType = cell.attrType local gtaAttrIdx = cell.gtaAttrIdx local cellValue = cell.value --format "gtaAttrIdx: % \n" gtaAttrIdx --format "updateCell:cellValue: % \n" cellValue if not multiMode then --single selection ( --row = rle.rageGrid.rows.item[e.RowIndex] nameCell = theRow.cells.item[0].value append theLights (getNodeByName nameCell) ) else --multi selection ( for row = 0 to rle.multiRowSelection.count - 1 do ( append theLights (getNodeByName(rle.multiRowSelection.item[row].cells.item[0].value)) --format "theLights: % \n" theLights ) ) --format "theLights: % \n" theLights --update the lights for theLight in theLights do ( --format "updateCell - attrType: % \n" attrType --if rle.__DEBUG__ then assert (attrType != undefined) message: ("undefined attrtype for: " + attr) case attrType of ( "String": ( --set light to property if gtaAttrIdx == 0 then ( setProperty theLight attr (cellValue as float) ) else ( setAttr theLight gtaAttrIdx (cellValue as float) ) ) "checkbox": ( --format "theLight: % cellValue: % attr: % \n" theLight rle.rageGrid.rows.item[e.RowIndex].cells.item[e.ColumnIndex].EditedFormattedValue attr if gtaAttrIdx == 0 then ( setProperty theLight attr (theRow.cells.item[e.ColumnIndex].EditedFormattedValue as BooleanClass) ) else ( setAttr theLight gtaAttrIdx (theRow.cells.item[e.ColumnIndex].EditedFormattedValue as BooleanClass) ) ) "Image": ( --if its a colour we need to get that from the bitmap --print "image" --get the colour from the cell image col = cellValue.getPixel 0 0 --format "colour: % % % \n" col.r col.g col.b if gtaAttrIdx == 0 then ( setProperty theLight attr (color col.r col.g col.b) ) else ( setAttr theLight gtaAttrIdx (color col.r col.g col.b) ) ) "combobox": ( --which enum is it, and whats its value. --format "enum: " --print cellValue case columnName of ( "Preset": ( rle.changePreset theLight cellValue theRow ) "Type": ( idx = finditem rle.rageLightTypes cellValue setProperty theLight attr idx ) "Flashiness": ( idx = findItem rle.flashOpts cellValue --max arrays are 1-based dotnet combox items 0-bsaed so idx - 1 setAttr theLight gtaAttrIdx (idx - 1) ) ) ) "spinner": ( --print "spinner" if gtaAttrIdx == 0 then ( setProperty theLight attr (cellValue as Float) ) else ( setAttr theLight gtaAttrIdx (cellValue as Float) ) ) default: ( --print "default" --set light to property if gtaAttrIdx == 0 then ( setProperty theLight attr cellValue ) else ( setAttr theLight gtaAttrIdx cellValue ) ) ) ) --Refresh the table --update only what we need. check for instances for any selected and add them --to and update list then update those rows only updateRowList = #() --get the lights for all the selected rows we have selectedRows = rle.rageGrid.selectedRows if selectedRows.count == 1 then ( for l = 0 to (selectedRows.count - 1) do ( --append the current selected row append updateRowList selectedRows.item[l] --find out what this light is --check for any instances of it nameCell = selectedRows.item[l].cells.item[0].value handle = selectedRows.item[l].tag theObject = maxOps.getNodeByHandle handle --find any instances InstanceMgr.GetInstances theObject &instances instanceNames = for inst in instances collect inst.name --find what rows they are in? for inst in instanceNames do ( for r = 0 to rle.rageGrid.rows.count - 1 do ( if inst == rle.rageGrid.rows.item[r].cells.item[0].value then append updateRowList rle.rageGrid.rows.item[r] ) ) ) ) else ( for l = 0 to (rle.multiRowSelection.count - 1) do --for l = 0 to (selectedRows.count - 1) do ( --append the current selected row append updateRowList rle.multiRowSelection.item[l] --find out what this light is --check for any instances of it nameCell = rle.multiRowSelection.item[l].cells.item[0].value handle = rle.multiRowSelection.item[l].tag theObject = maxOps.getNodeByHandle handle --find any instances InstanceMgr.GetInstances theObject &instances instanceNames = for inst in instances collect inst.name --find what rows they are in? for inst in instanceNames do ( for r = 0 to rle.rageGrid.rows.count - 1 do ( if inst == rle.rageGrid.rows.item[r].cells.item[0].value then append updateRowList rle.rageGrid.rows.item[r] ) ) ) ) /* ( --append the current selected row append updateRowList selectedRows.item[l] --find out what this light is --check for any instances of it nameCell = selectedRows.item[l].cells.item[0].value handle = selectedRows.item[l].tag theObject = maxOps.getNodeByHandle handle --find any instances InstanceMgr.GetInstances theObject &instances instanceNames = for inst in instances collect inst.name --find what rows they are in? for inst in instanceNames do ( for r = 0 to rle.rageGrid.rows.count - 1 do ( if inst == rle.rageGrid.rows.item[r].cells.item[0].value then append updateRowList rle.rageGrid.rows.item[r] ) ) ) */ --remove any dupes updateRowList = makeuniquearray updateRowList --Update these rows with theLights new values previously set. for i = 1 to updateRowList.count do ( theLight = getNodeByName updateRowList[i].cells.item[0].value --validate against presets local presetValidation = lightPresetCore.presetComparator theLight --format "presetValidation: % \n" presetValidation if presetValidation == "NONE" then ( setAppData theLight 1 undefined --set the preset column value theRow.cells.item[2].value = undefined ) else ( setAppData theLight 1 presetValidation --set the preset column value theRow.cells.item[2].value = presetValidation ) --update rows if i != e.RowIndex then ( rle.populateRow updateRowList[i] theLight ) ) /* for r = 0 to (rle.rageGrid.rows.count - 1) do ( if r != e.RowIndex then ( theLight = getNodeByName rle.rageGrid.rows.item[r].cells.item[0].value rle.populateRow rle.rageGrid.rows.item[r] theLight ) ) */ --clear any multiSelect markers rle.multiRowSelection = #() for r = 0 to s.rows.count - 1 do ( row = s.rows.item[r] rowHeader = row.headerCell.value = "" --rowHeader.value = "" ) --if multiMode then rle.listLights() --rle.listLights() --theLight = getnodebyname nameCell --format "RowIndex: % \n" e.RowIndex --rle.populateRow rle.rageGrid.rows.item[e.RowIndex] theLight ), fn Event_RageGrid_doubleClick s e = ( --print "DoubleClick" --e.rowIndex nameCell = rle.rageGrid.rows.item[e.RowIndex].cells.item[0].value select (getNodeByName nameCell) ), fn cellChanged s e = ( --print "Cell Changed" cell = rle.getCell e rle.checkBoxState = cell.value ), fn Event_standardPropsCheckBox_Changed s e = ( rle.activePropertyFilter = "Standard" if s.checked == true then ( rle.timeCyclePropsCheckBox.checked = false rle.lightPhotoPropsCheckBox.checked = false ) else ( rle.timeCyclePropsCheckBox.checked = true rle.lightPhotoPropsCheckBox.checked = true ) rle.activePropertyColumnFilter = rle.columns --update column visibility rle.ColumnVisibilityControl() ), fn Event_timeCyclePropsCheckBox_Changed s e = ( rle.activePropertyFilter = "TimeCycle" if s.checked == true then ( rle.standardPropsCheckBox.checked = false rle.lightPhotoPropsCheckBox.checked = false ) else ( rle.standardPropsCheckBox.checked = true rle.lightPhotoPropsCheckBox.checked = true ) rle.activePropertyColumnFilter = rle.timeCycleColumns --update column visibility rle.ColumnVisibilityControl() ), fn Event_lightPhotoPropsCheckBox_Changed s e = ( rle.activePropertyFilter = "LightPhoto" if s.checked == true then ( rle.standardPropsCheckBox.checked = false rle.timeCyclePropsCheckBox.checked = false ) else ( rle.standardPropsCheckBox.checked = true rle.timeCyclePropsCheckBox.checked = true ) rle.activePropertyColumnFilter = rle.lightPhotoColumns --update column visibility rle.ColumnVisibilityControl() ), --Instance display row colouring fn Event_instanceDisplayCheckBox_Changed s e = ( --change datagrid highlighting if s.checked == true then ( rle.displayInstances = true ) else ( rle.displayInstances = false ) ), fn Event_RageGrid_RowEnter s e = ( if rle.displayInstances then --do row colouring ( --rle.rageGrid.rows.item[e.RowIndex].Style.BackColor = Color.Yellow; --find the node for this row and check for instances nameCell = rle.rageGrid.rows.item[e.RowIndex].cells.item[0].value handle = rle.rageGrid.rows.item[e.RowIndex].tag theObject = maxOps.getNodeByHandle handle --format "light from tag: % \n" theObject --find any instances InstanceMgr.GetInstances theObject &instances instanceNames = for inst in instances collect inst.name --format "Instances: % \n" instances --match up to any rows in the grid and adjust the colour rowCollection = rle.rageGrid.Rows for row = 0 to (rowCollection.count - 1) do --while rowIt.moveNext() != false do ( --format "tomatch: % % \n" instanceNames rowCollection.Item[row].cells.item[0].value if findItem instanceNames rowCollection.Item[row].cells.item[0].value != 0 then --we got a match ( rowCollection.Item[row].DefaultCellStyle.backColor = rle.rageGridCol_Peach ) ) ) ), fn Event_RageGrid_RowLeave s e = ( if rle.displayInstances then --clear row colouring ( --rle.rageGrid.rows.item[e.RowIndex].Style.BackColor = Color.Empty rowCollection = rle.rageGrid.Rows for row = 0 to (rowCollection.count - 1) do ( rowCollection.Item[row].DefaultCellStyle.backColor = rle.rageGridCol_Empty ) ) ), --/Instance display row colouring ------------------------------------------------ -- UI ------------------------------------------------ fn createColumnSelectorUI = ( --create the window columnSelectorForm = dotNetObject "maxCustomControls.maxForm" columnSelectorForm.Size = dotNetObject "System.Drawing.Size" 200 500 columnSelectorForm.Text = "Select Columns" columnSelectorForm.startPosition = (dotNetClass "System.Windows.Forms.FormStartPosition").Manual columnSelectorForm.Location = dotNetObject "system.drawing.point" startPos.x startPos.y flowLayout = dotNetObject "System.Windows.Forms.FlowLayoutPanel" flowLayout.dock = (dotNetClass "System.Windows.Forms.DockStyle").Fill flowLayout.width = 120 flowLayout.FlowDirection = (dotnetClass"System.Windows.Forms.FlowDirection").TopDown --base column switches on currently selected property filter --case activePropertyColumnFilter of --add checkboxes columnNames = #() case rle.activePropertyFilter of ( "Standard": ( columnNames = for n in standard_UI_property_Map collect n.ui ) "TimeCycle": ( columnNames = for i = 1 to 26 collect lightPhotoAttrNames[i] ) "LightPhoto": ( columnNames = for i = 28 to lightPhotoAttrNames.count collect lightPhotoAttrNames[i] ) ) --check whether it is currently visible local visibleColumns = #() columnsIt = rle.rageGrid.Columns.GetEnumerator() while columnsIt.MoveNext() != false do ( --format "columnNames:% header: % \n" columnNames columnsIt.current.headerText if columnsIt.Current.visible == true then append visibleColumns columnsIt.Current.headerText ) for c = 1 to columnNames.count do ( thisLabel = columnNames[c] --print thisLabel chkBox = dotNetObject "System.Windows.Forms.CheckBox" chkBox.Text = thisLabel if findItem visibleColumns thisLabel != 0 then ( chkBox.checked = true ) else ( chkBox.checked = false ) flowLayout.controls.add chkBox ) columnSelectorForm.controls.add flowLayout --close event triggers column visibility update dotNet.AddEventHandler columnSelectorForm "FormClosed" Event_ColumnSelector_FormClosed ), fn ColumnVisibilityControl = ( --for each column check if its in the activePropertyColumnFilter --if not set its visibility to false --iterate the columns columnsIt = rle.rageGrid.Columns.GetEnumerator() while columnsIt.MoveNext() != false do ( --if name is in colums arrray its visible otherwise not if findItem activePropertyColumnFilter columnsIt.Current.HeaderText != 0 then ( columnsIt.Current.visible = true ) else ( columnsIt.Current.visible = false ) ) --refresh the grid rle.rageGrid.Refresh() ), fn createColumns = ( fn createColumn columnText columnVisible columnType GtaAttrIdx:0 = ( case columnType of ( "checkbox": ( local theColumn = dotNetObject "System.Windows.Forms.DataGridViewCheckBoxColumn" theColumn.headerText = columnText --dimensions --theColumn.MinimumWidth = 30 --theColumn.FillWeight = 100 theColumn.AutoSizeMode = columnResize_DisplayedCells --tag data theColumn.tag = GtaAttrIdx --visibility theColumn.visible = columnVisible --add rageGrid.Columns.Add theColumn ) "spinner": ( local theColumn = dotNetObject "System.Windows.Forms.DataGridViewTextBoxColumn" theColumn.headerText = columnText --dimensions theColumn.MinimumWidth = 30 theColumn.FillWeight = 100 theColumn.AutoSizeMode = columnResize_DisplayedCells --tag data theColumn.tag = GtaAttrIdx --visibility theColumn.visible = columnVisible --add rageGrid.Columns.Add theColumn ) "combobox": ( local theColumn = dotNetObject "System.Windows.Forms.DataGridViewComboBoxColumn" theColumn.FlatStyle = (dotNetClass "System.Windows.Forms.FlatStyle").Flat theColumn.headerText = columnText --dimensions theColumn.MinimumWidth = 100 --theColumn.FillWeight = 100 case theColumn.headerText of ( "Preset": ( --print "Preset" --print rageLightPresetNames theColumn.DataSource = rageLightPresetNames ) "Type": ( --print "Type" --print rageLightTypes theColumn.DataSource = rageLightTypes ) "Flashiness": ( theColumn.DataSource = flashOpts ) ) --tag data theColumn.tag = GtaAttrIdx --visibility theColumn.visible = columnVisible --dotNet.AddEventHandler theColumn "click" Event_Combo_Click --add the column rageGrid.Columns.Add theColumn theColumn = undefined ) "Image": ( local theColumn = dotNetObject "System.Windows.Forms.DataGridViewImageColumn" theColumn.headerText = columnText --dimensions theColumn.width = 30 --theColumn.MinimumWidth = 30 --theColumn.FillWeight = 50 theColumn.AutoSizeMode = columnResize_DisplayedCells --tag data theColumn.tag = GtaAttrIdx --visibility theColumn.visible = columnVisible --add rageGrid.Columns.Add theColumn ) default: ( local theColumn = dotNetObject "System.Windows.Forms.DataGridViewTextBoxColumn" theColumn.headerText = columnText if theColumn.headerText == "Name" then ( theColumn.ReadOnly = true --dimensions --theColumn.MinimumWidth = 100 --theColumn.FillWeight = 300 theColumn.AutoSizeMode = columnResize_DisplayedCells --tag data theColumn.tag = GtaAttrIdx ) else ( --dimensions theColumn.MinimumWidth = 30 theColumn.FillWeight = 100 theColumn.AutoSizeMode = columnResize_DisplayedCells --tag data theColumn.tag = GtaAttrIdx ) --visibility theColumn.visible = columnVisible --add rageGrid.Columns.Add theColumn ) ) ) --Standard attr columns for c = 1 to standard_UI_property_Map.count do ( columnText = standard_UI_property_Map[c].ui columnVisible = true if findItem columns columnText == 0 then columnVisible = false columnType = undefined UIColumn_Type_MapDict.TryGetValue columnText &columnType createColumn columnText columnVisible columnType ) --Gta Light attr columns for c = 1 to (GetNumAttr "Gta LightPhoto") - 1 do --attr count - 1 ( columnText = GetAttrName "Gta LightPhoto" c columnVisible = true if findItem activePropertyColumnFilter columnText == 0 then columnVisible = false columnType = GetControlType "Gta LightPhoto" columnText --add the "Gta Light" attr index into the .tag property --Create the column --format "Column Name: % Type: % \n" columnText columnType --Check for exclusion list if findItem UIColumnExclusion columnText == 0 then ( createColumn columnText columnVisible columnType GtaAttrIdx:c ) ) ), fn cleanClosure = ( callbacks.removeScripts id:#RageLightEditor gc light:true ), fn createUI = ( if editorForm != undefined then editorForm.close() --Set the parent of the form to be Max. --Get the max handle pointer. maxHandlePointer=(Windows.GetMAXHWND()) --Convert the HWND handle of Max to a dotNet system pointer sysPointer = DotNetObject "System.IntPtr" maxHandlePointer --Create a dotNet wrapper containing the maxHWND maxHwnd = DotNetObject "MaxCustomControls.Win32HandleWrapper" sysPointer ------------------- --form setup ------------------- editorForm = dotNetObject "maxCustomControls.maxForm" editorForm.Size = dotNetObject "System.Drawing.Size" formWidth formHeight editorForm.Text = "Rage Light Editor" editorForm.startPosition = (dotNetClass "System.Windows.Forms.FormStartPosition").Manual editorForm.Location = dotNetObject "system.drawing.point" startPos.x startPos.y --editorForm.FormBorderStyle = FBS_FixedToolWindow editorForm.MaximumSize = dotNetObject "System.Drawing.Size" 1600 1024 editorForm.MinimumSize = dotNetObject "System.Drawing.Size" 512 10 dotNet.AddEventHandler editorForm "Closing" cleanClosure dotNet.AddEventHandler editorForm "Resize" Event_editorForm_Resize ------------------- --table setup ------------------- editorTable = dotNetObject "System.Windows.Forms.TableLayoutPanel" --editorTable.backColor = RGB_BackroundGrey editorTable.dock = (dotNetClass "System.Windows.Forms.DockStyle").Fill editorTable.cellBorderStyle = (dotNetClass "System.Windows.Forms.TableLayoutPanelCellBorderStyle").single editorTable.columnCount = 1 editorTable.columnStyles.add (dotNetObject "ColumnStyle" (dotNetClass "System.Windows.Forms.SizeType").Percent 100) -- (RS_dotNetObject.columnStyleObject "percent" 100) editorTable.rowCount = 4 --Banner editorTable.rowStyles.add (dotNetObject "RowStyle" (dotNetClass "System.Windows.Forms.SizeType").Absolute 42) --Top buttons editorTable.rowStyles.add (dotNetObject "RowStyle" (dotNetClass "System.Windows.Forms.SizeType").Absolute 56) --(RS_dotNetObject.rowStyleObject "absolute" buttonRowHeight) --Light list editorTable.rowStyles.add (dotNetObject "RowStyle" (dotNetClass "System.Windows.Forms.SizeType").Percent 100) --(RS_dotNetObject.rowStyleObject "percent" 100) --Bottom buttons editorTable.rowStyles.add (dotNetObject "RowStyle" (dotNetClass "System.Windows.Forms.SizeType").Absolute buttonRowHeight) editorForm.controls.add editorTable -------------------------------------- -- R* BANNER -------------------------------------- rsBannerPanel = dotNetObject "Panel" rsBannerPanel.Dock = rsBannerPanel.Dock.Fill local banner = makeRsBanner dn_Panel:rsBannerPanel wiki:"RageLightEditor" doOutline:False filename:(getThisScriptFilename()) banner.setup() --Add to table layout: editorTable.Controls.Add rsBannerPanel -------------------------------------- -- TOP ROW BUTTONS -------------------------------------- topRowBtnTable = dotNetObject "System.Windows.Forms.TableLayoutPanel" --editorTable.backColor = RGB_BackroundGrey topRowBtnTable.dock = (dotNetClass "System.Windows.Forms.DockStyle").Fill --topRowBtnTable.cellBorderStyle = (dotNetClass "System.Windows.Forms.TableLayoutPanelCellBorderStyle").single topRowBtnTable.columnCount = 3 topRowBtnTable.columnStyles.add (dotNetObject "ColumnStyle" (dotNetClass "System.Windows.Forms.SizeType").Absolute 270) -- (RS_dotNetObject.columnStyleObject "percent" 100) topRowBtnTable.columnStyles.add (dotNetObject "ColumnStyle" (dotNetClass "System.Windows.Forms.SizeType").Absolute 120) topRowBtnTable.columnStyles.add (dotNetObject "ColumnStyle" (dotNetClass "System.Windows.Forms.SizeType").Absolute 75) topRowBtnTable.rowCount = 1 --topRowBtnTable.rowStyles.add (dotNetObject "RowStyle" (dotNetClass "System.Windows.Forms.SizeType").Percent 100) instanceDisplayCheckBox = dotNetObject "System.Windows.Forms.CheckBox" instanceDisplayCheckBox.text = "Display Instances" instanceDisplayCheckBox.margin = dotNetObject "System.Windows.Forms.Padding" 12 instanceDisplayCheckBox.width = 150 instanceDisplayCheckBox.flatStyle = (dotNetClass "System.Windows.Forms.FlatStyle").System --instanceDisplayCheckBox.location = dotnetobject "System.Drawing.Point" 0 20 dotNet.AddEventHandler instanceDisplayCheckBox "Click" Event_instanceDisplayCheckBox_Changed columnSelectorButton = dotNetObject "System.Windows.Forms.Button" columnSelectorButton.text = "Column Filter" columnSelectorButton.width = 100 columnSelectorButton.margin = dotNetObject "System.Windows.Forms.Padding" 12 columnSelectorButton.flatStyle = (dotNetClass "System.Windows.Forms.FlatStyle").System --columnSelectorButton.dock = (dotNetClass "System.Windows.Forms.DockStyle").Fill --columnSelectorButton.location = dotnetobject "System.Drawing.Point" 0 20 dotNet.AddEventHandler columnSelectorButton "Click" Event_ColumnSelector_Click --Property filter propsGroupBox = dotNetObject "System.Windows.Forms.GroupBox" propsGroupBox.text = "Properties Filter" propsGroupBox.size = dotnetobject "System.Drawing.size" 255 40 propsGroupBox.flatStyle = (dotNetClass "System.Windows.Forms.FlatStyle").System standardPropsCheckBox = dotNetObject "System.Windows.Forms.CheckBox" standardPropsCheckBox.text = "Standard" standardPropsCheckBox.width = 70 standardPropsCheckBox.location = dotnetobject "System.Drawing.Point" 10 12 standardPropsCheckBox.checked = true dotNet.AddEventHandler standardPropsCheckBox "Click" Event_standardPropsCheckBox_Changed timeCyclePropsCheckBox = dotNetObject "System.Windows.Forms.CheckBox" timeCyclePropsCheckBox.text = "Time Cycle" timeCyclePropsCheckBox.width = 80 timeCyclePropsCheckBox.location = dotnetobject "System.Drawing.Point" 85 12 dotNet.AddEventHandler timeCyclePropsCheckBox "Click" Event_timeCyclePropsCheckBox_Changed lightPhotoPropsCheckBox = dotNetObject "System.Windows.Forms.CheckBox" lightPhotoPropsCheckBox.text = "Light Photo" lightPhotoPropsCheckBox.width = 80 lightPhotoPropsCheckBox.location = dotnetobject "System.Drawing.Point" 170 12 dotNet.AddEventHandler lightPhotoPropsCheckBox "Click" Event_lightPhotoPropsCheckBox_Changed propsGroupBox.controls.add standardPropsCheckBox propsGroupBox.controls.add timeCyclePropsCheckBox propsGroupBox.controls.add lightPhotoPropsCheckBox --/Property filter --add to btn table topRowBtnTable.Controls.Add propsGroupBox 0 0 topRowBtnTable.Controls.Add columnSelectorButton 1 0 topRowBtnTable.Controls.Add instanceDisplayCheckBox 2 0 --add to editorTable editorTable.Controls.Add topRowBtnTable 0 1 -------------------------------------- -- LIGHT LIST -------------------------------------- --listview --rageList = dotnetobject "System.Windows.Forms.ListView" --rageList.Dock = (dotNetClass "System.Windows.Forms.DockStyle").Fill --rageList.View = (dotNetClass "System.Windows.Forms.View").List --rageList.FullRowSelect = true --rageList.GridLines = true --DataGrid rageGrid = dotnetObject "System.Windows.Forms.DataGridView" rageGrid.dock = (dotNetClass "System.Windows.Forms.DockStyle").Fill rageGrid.AllowUserToAddRows = false rageGrid.AllowUserToDeleteRows = false rageGrid.AllowUserToOrderColumns = true --rageGrid.ReadOnly = true rageGrid.AllowUserToResizeRows = false rageGrid.AutoSizeColumnsMode = (dotNetClass "System.Windows.Forms.DataGridViewAutoSizeColumnsMode").AllCells rageGrid.SelectionMode = (dotNetClass "System.Windows.Forms.DataGridViewSelectionMode").FullRowSelect --colours rageGrid.DefaultCellStyle.SelectionBackColor = rageGridCol_LightBlue rageGrid.DefaultCellStyle.ForeColor = rageGridCol_Text rageGrid.DefaultCellStyle.SelectionForeColor = rageGridCol_TextSelected rageGrid.RowsDefaultCellStyle.BackColor = rageGridCol_OffWhite rageGrid.AlternatingRowsDefaultCellStyle.BackColor = rageGridCol_LightGrey --add columns rageGrid.ColumnHeadersVisible = true --columnStyle columnStyle = dotnetObject "System.Windows.Forms.DataGridViewCellStyle" columnStyle.Alignment = contentAlignMent_midCenter rageGrid.DefaultCellStyle.Alignment = contentAlignMent_midCenter --create columns based on data types createColumns() --Populate rows listLights() dotNet.AddEventHandler rageGrid "CellContentClick" Event_RageGrid_cellClick --dotNet.AddEventHandler rageGrid "CellValueChanged" cellChanged --dotNet.AddEventHandler rageGrid "CellParsing" updateCell dotNet.AddEventHandler rageGrid "CellEndEdit" Event_RageGrid_updateCell dotNet.AddEventHandler rageGrid "SelectionChanged" Event_RageGrid_updateSelection dotNet.AddEventHandler rageGrid "CellContentDoubleClick" Event_RageGrid_doubleClick --dotNet.AddEventHandler rageGrid "CurrentCellDirtyStateChanged" Event_RageGrid_DirtyCell dotNet.AddEventHandler ragegrid "RowEnter" Event_RageGrid_RowEnter dotNet.AddEventHandler ragegrid "RowLeave" Event_RageGrid_RowLeave --rageGrid.ReadOnly = true editorTable.Controls.Add rageGrid 0 2 -------------------------------------- -- BOTTOM BUTTONS -------------------------------------- btmFlowLayout = dotNetObject "System.Windows.Forms.FlowLayoutPanel" btmFlowLayout.dock = (dotNetClass "System.Windows.Forms.DockStyle").Fill btmFlowLayout.width = 120 btmFlowLayout.FlowDirection = (dotnetClass"System.Windows.Forms.FlowDirection").LeftToRight editorTable.Controls.Add btmFlowLayout 0 3 --show the form editorForm.show(maxHwnd) ) )--END STRUCT --main if rle != undefined then rle.editorForm.close(); gc() rle = RageLightEditor() rle.createUI()