Files
2025-09-29 00:52:08 +02:00

1589 lines
47 KiB
Plaintext
Executable File

/*
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()