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

554 lines
16 KiB
Plaintext
Executable File

struct RsBannerStruct
(
--------------------------------------------------------------
-- USAGE:
-- .NET FORM TO HOLD THE IMAGES:
-- dotNetControl rsBannerPanel "Panel" pos:[0,0] height:32 width:ROLLOUT.Width
-- INSTANCE THE STRUCT:
-- local banner = makeRsBanner dn_Panel:rsBannerPanel versionNum:1.10 versionName:"Some Phrase" wiki:"WIKI_NAME" filename:(getThisScriptFilename())
-- SET UP THE BANNER:
-- on ROLLOUT open do banner.setup()
--------------------------------------------------------------
width = 300,
mail = "*Default_Tech_Art@rockstarnorth.com",
colourScheme, wiki,
dn_panel, filename,
versionNum, versionName = "",
versionText = "",
iconDir = (RsConfigGetWildwestDir() + "script/3dsMax/UI/"),
rsLogo_bmp = "WW_banner_rsLogo.png",
rsMail_bmp = "WW_banner_mail.png",
rsHelp_bmp = "WW_banner_wiki.png",
-- doBottomLine overrides doOutline:
doOutline = true, doBottomLine = false,
trackUsage = true,
usagePath,
-- Registry address showing path to Bugstar.exe:
BugstarClientPathReg = @"HKEY_CLASSES_ROOT\Bugstar\Shell\Open\Command",
BugstarTestMode = False, -- If TRUE, Bugstar-Dev is used instead of Bugstar
-------------------------------------
fn launchWiki Sender Arg =
(
if (Sender.tag != undefined) do ShellLaunch ("https://devstar.rockstargames.com/wiki/index.php/" + Sender.tag as string) ""
),
-- Returns Perforce version of filename, including its change-version:
fn getP4filename =
(
if (not isKindOf filename String) do return undefined
pushPrompt "Getting script's Perforce path..."
local fileP4data = ::gRsPerforce.run "files" #(filename) returnResult:True
fileP4data = fileP4data.Records[1]
popPrompt()
if (fileP4data == undefined) then
(
return undefined
)
else
(
local retVal = stringStream ""
format "%#%" fileP4data.Fields.Item["depotFile"] fileP4data.Fields.Item["rev"] to:retVal
return (retVal as string)
)
),
-- Add bug for bannered tool in Bugstar:
fn addBug =
(
-- Build data to add to bug:
local bugArgs = stringStream ""
(
format " newbug \"%\n\n" versionText filename to:bugArgs
-- Get Perforce path/version for file:
if (isKindOf filename String) do
(
-- Include Perforce path, if found:
local useFilename = getP4filename()
-- Otherwise include local filename:
if (useFilename == undefined) do
(
useFilename = filename
)
format "%\n\n" useFilename to:bugArgs
)
format "\"" to:bugArgs
)
--format "Adding bug to Bugstar:\n\t%\n" (bugArgs as string)
local BugstarClientPath = undefined
-- Get Bugstar.exe's path from registry:
(
local regTokens = filterString BugstarClientPathReg "\\"
try
(
-- Start with root-key:
local currentKey = (execute regTokens[1])
-- Walk down to requested registry-address:
for tokenNum = 2 to regTokens.count do
(
registry.openKey currentKey regTokens[tokenNum] accessRights:#readOnly key:&currentKey
)
registry.queryValue currentKey "" value:&BugstarClientPath
)
catch
(
print (registry.getLastError())
return false
)
if (isKindOf BugstarClientPath string) do
(
-- Trim argument-token off end of acquired path-string:
BugstarClientPath = toLower (substituteString BugstarClientPath " \"%1\"" "")
-- Set to use bugstar-dev instead of bugstar:
if BugstarTestMode do
(
BugstarClientPath = substituteString BugstarClientPath "bugstar" "bugstar-dev"
)
)
)
-- Abort if Bugstar path wasn't found in registry:
if (BugstarClientPath == undefined) do return False
local runString = (BugstarClientPath + (bugArgs as string))
format "%\n" runString
ShellLaunch BugstarClientPath (bugArgs as string)
),
fn mailClicked Sender Arg =
(
global RsClickedBanner = Sender.Parent.Tag.Value
rcMenu RsMenu_BannerMail
(
fn hasMail = ((isKindOf RsClickedBanner.Mail String) and (RsClickedBanner.Mail != ""))
menuItem itmSendMail "Send mail" Filter:hasMail
menuItem itmAddBug "Add bug"
fn clearUp =
(
globalVars.remove #RsClickedBanner
)
on itmSendMail picked do
(
local mailText = ("mailto:" + RsClickedBanner.Mail)
clearUp()
ShellLaunch mailText ""
)
on itmAddBug picked do
(
RsClickedBanner.addBug()
clearUp()
)
-- On menu-open, customise text for commands:
on RsMenu_BannerMail open do
(
if hasMail() do
(
itmSendMail.text = ("Mail to: " + RsClickedBanner.Mail)
)
itmAddBug.text = ("Add bug for: " + RsClickedBanner.versionText)
)
)
popUpMenu RsMenu_BannerMail
),
fn logoClicked Sender Arg =
(
local rightClick = arg.button.equals arg.button.right
if rightClick do
(
global RsClickedBanner = sender.Parent.Tag.Value
rcMenu RsMenu_Banner
(
fn hasFilename = (isKindOf RsClickedBanner.filename String)
menuItem itmShowUsage "Show Tool Usage Folder"
menuItem itmRandomPhrase "Generate Random Phrases"
menuItem itmEditTool "Edit Script" filter:hasFilename
menuItem itmAddBug "Add bug"
separator sepA
menuItem itmCopyVersion "Copy Tool Info to Clipboard"
fn clearUp =
(
globalVars.remove #RsClickedBanner
)
-- Show usage-folder in Explorer
on itmShowUsage picked do
(
if not (isKindOf RsClickedBanner.usagePath string) do
(
clearUp()
return false
)
local filePath = RsMakeBackSlashes (RsClickedBanner.usagePath)
clearUp()
format "\n%\n" filePath
shellLaunch "explorer.exe" filePath
)
-- Generate random phrases (for use as version-names)
on itmRandomPhrase picked do
(
clearUp()
filein (RsConfigGetWildWestDir() + "script/3dsmax/_config_files/wildwest_header.ms")
local outText = stringStream ""
local phraseCount = 50
for item in (::RsRandomPhrase count:50) do
(
format "%\n" item to:outText
)
RScreateTextWindow title:((phraseCount as string) + " Random Phrases") text:(outText as string) width:400 height:720
)
on itmCopyVersion picked do
(
local verText = stringStream ""
format "%" RsClickedBanner.versionText to:verText
-- Include local and Perforce paths, if found:
local filename = RsClickedBanner.filename
if (isKindOf filename String) do
(
format "\n%" filename to:verText
local p4filename = RsClickedBanner.getP4filename()
if (isKindOf p4filename String) do
(
format "\n%" p4filename to:verText
)
)
clearUp()
verText = (verText as string)
format "\n%\n" verText
setClipboardText verText
)
on itmEditTool picked do
(
local filename = RsClickedBanner.filename
clearUp()
edit filename
)
on itmAddBug picked do
(
RsClickedBanner.addBug()
clearUp()
)
on RsMenu_Banner open do
(
if (hasFilename()) do
(
itmEditTool.text = ("Edit script: " + (filenameFromPath RsClickedBanner.filename))
)
itmAddBug.text = ("Add bug for: " + RsClickedBanner.versionText)
)
)
popUpMenu RsMenu_Banner
)
),
fn setup =
(
-- Get filename of calling function from stack:
(
-- Get function-call line-info:
local CallLine = (gRsDebugStack.GetCallLine Level:3 Default:Undefined)
if (CallLine != undefined) and (CallLine != "") do
(
-- Extract filename from 'CallLine':
local CallLineStream = (CallLine as StringStream)
skipToString CallLineStream "filename: "
local ThisFileName = readDelimitedString CallLineStream ";"
-- Use filename if path is to proper file:
if ((GetFilenameFile ThisFileName) != "") do
(
Filename = ThisFileName
)
)
)
--format "Setup RsBanner: %\n" (filename as string)
-- Store link to this struct in panel-tag:
dn_Panel.Tag = (dotNetMXSValue This)
local icon_size = 32
local pbSizeMode = dotNetClass "PictureBoxSizeMode"
local AnchorStyles = dotNetClass "AnchorStyles"
local DockStyle = dotNetClass "DockStyle"
-----------------------------------
if (isKindOf dn_Panel dotNetObject) then
(
dn_Panel.height = icon_size
dn_Panel.width = width
-- Just draw bottom line if control is positioned at top of rollout:
if (dn_Panel.Location.Y == 0) do
(
doBottomLine = True
)
)
else
(
if (dn_Panel.Pos.Y == 0) do
(
doBottomLine = True
)
)
-----------------------------------
-- Set colour-scheme:
local colourClass = DotNetClass "System.Drawing.Color"
local colours = case colourScheme of
(
#north:(dataPair back:(colourClass.FromArgb 62 107 185) fore:undefined)
#vancouver:(dataPair back:(colourClass.FromArgb 33 136 24) fore:undefined)
#toronto:(dataPair back:(colourClass.FromArgb 238 31 29) fore:undefined)
#sandiego:(dataPair back:(colourClass.FromArgb 170 42 140) fore:undefined)
#london:(dataPair back:(colourClass.FromArgb 255 54 164) fore:undefined)
#leeds:(dataPair back:colourClass.white fore:[17,40,110])
#eval:(dataPair back:colourClass.red fore:undefined)
-- Default colourscheme:
default:(dataPair back:(colourClass.FromArgb 246 186 0) fore:undefined)
)
local bgColour = colours.back
local fgColour = colours.fore
local outlineClr = colourClass.FromArgb 255 colourClass.black
-----------------------------------
-- Set background-colour and add outline:
dn_Panel.BackColor = bgColour
if doOutline and not doBottomLine do
(
local topLine_picBox = dotnetobject "PictureBox"
topLine_picBox.BackColor = outlineClr
topLine_picBox.Dock = DockStyle.Top
topLine_picBox.Height = 1
dn_Panel.controls.add topLine_picBox
local lftLine_picBox = dotnetobject "PictureBox"
lftLine_picBox.BackColor = outlineClr
lftLine_picBox.Dock = DockStyle.Left
lftLine_picBox.Width = 1
dn_Panel.controls.add lftLine_picBox
local rgtLine_picBox = dotnetobject "PictureBox"
rgtLine_picBox.BackColor = outlineClr
rgtLine_picBox.Dock = DockStyle.Right
rgtLine_picBox.Width = 1
dn_Panel.controls.add rgtLine_picBox
)
if doOutline or doBottomLine do
(
local botLine_picBox = dotnetobject "PictureBox"
botLine_picBox.BackColor = outlineClr
botLine_picBox.Dock = DockStyle.Bottom
botLine_picBox.Height = 1
dn_Panel.controls.add botLine_picBox
)
-- Don't add icons if outsourcer:
if (not gRsIsOutSource) do
(
-----------------------------------
-- Add R* logo-icon:
local rsLogo_picBox = dotnetobject "PictureBox"
rsLogo_picBox.size = dotnetobject "System.Drawing.Size" icon_size icon_size
local rsLogo_image = (dotNetclass "System.Drawing.Image").fromfile (iconDir + rsLogo_bmp)
-- Recolour R* logo, if text isn't black:
if (fgColour != undefined) do
(
for x = 0 to (icon_size - 1) do
(
for y = 0 to (icon_size - 1) do
(
local getClr = rsLogo_image.getPixel X Y
local clrPos = [getClr.R, getClr.G, getClr.B]
clrPos += fgColour
for n = 1 to 3 do
(
if clrPos[n] > 255 do clrPos[n] = 255
)
local setClr = colourClass.FromArgb getClr.A clrPos[1] clrPos[2] clrPos[3]
rsLogo_image.setPixel X Y setClr
)
)
)
rsLogo_picBox.image = rsLogo_image
rsLogo_picBox.anchor = AnchorStyles.Left
rsLogo_picBox.Location = dotnetobject "System.Drawing.Point" 0 0
dn_Panel.controls.add rsLogo_picBox
-- Add click-event to logo:
dotNet.addEventHandler rsLogo_picBox "click" logoClicked
dotNet.setLifetimeControl rsLogo_picBox #dotnet -- STOP GC() FROM REMOVING THE EVENT
local hasFilename = (isKindOf filename String)
local hasVersionNum = (versionNum != undefined)
local hasVersionName = (versionName != "")
if hasFilename do
(
versionText = (getFilenameFile filename)
)
if hasVersionNum or hasVersionName do
(
local versionLabelText = stringStream ""
if (hasVersionNum) do (format "v%" (formattedprint versionNum format:".2f") to:versionLabelText)
if (hasVersionNum and hasVersionName) do (format ":" to:versionLabelText)
if (hasVersionName) do (format "%" versionName to:versionLabelText)
versionText += (" [" + (versionLabelText as string) + "]")
local versionLabel = dotnetobject "Label"
versionLabel.ForeColor = colourClass.black
versionLabel.Location.X = rsLogo_picBox.Right
versionLabel.Location.Y = rsLogo_picBox.Top + 6
versionLabel.Text = (replace_LF_with_CRLF (versionLabelText as string))
-- Set label-size to match the extents of its text:
local textSize = (versionLabel.createGraphics()).measureString versionLabel.text versionLabel.font
versionLabel.width = (textSize.width + 8)
versionLabel.height = (textSize.height + 8)
dn_Panel.controls.add versionLabel
-- Add click-event to label too:
dotNet.addEventHandler versionLabel "click" logoClicked
dotNet.setLifetimeControl versionLabel #dotnet -- STOP GC() FROM REMOVING THE EVENT
)
-----------------------------------
local rsMail_picBox = dotnetobject "PictureBox"
rsMail_picBox.tag = mail
rsMail_picBox.size = dotnetobject "System.Drawing.size" icon_size icon_size
local rsMail_image = (dotNetclass "System.Drawing.image").fromfile (iconDir + rsMail_bmp)
rsMail_picBox.image = rsMail_image
rsMail_picBox.anchor = AnchorStyles.Right
rsMail_picBox.Location = dotnetobject "System.Drawing.Point" (dn_Panel.width - (2 * icon_size)) 0
dn_Panel.controls.add rsMail_picBox
dotNet.addEventHandler rsMail_picBox "click" mailClicked
dotNet.setLifetimeControl rsMail_picBox #dotnet -- STOP GC() FROM REMOVING THE EVENT
-----------------------------------
if (isKindOf wiki string) and (wiki != "") then
(
local rsHelp_picBox = dotnetobject "PictureBox"
rsHelp_picBox.tag = wiki
rsHelp_picBox.size = dotnetobject "System.Drawing.size" icon_size icon_size
local rsHelp_image = (dotNetclass "System.Drawing.image").fromfile (iconDir + rsHelp_bmp)
rsHelp_picBox.image = rsHelp_image
rsHelp_picBox.anchor = AnchorStyles.Right
rsHelp_picBox.Location = dotnetobject "System.Drawing.Point" (dn_Panel.width - icon_size) 0
dn_Panel.controls.add rsHelp_picBox
dotNet.addEventHandler rsHelp_picBox "click" launchWiki
dotNet.setLifetimeControl rsHelp_picBox #dotnet -- STOP GC() FROM REMOVING THE EVENT
)
else
(
rsMail_picBox.Location.X += icon_size
)
-------------------------------------
-- Run usage-snooper code for the calling-script:
if trackUsage and (isKindOf filename string) do
(
if (::RsCollectToolUsageData == undefined) do
(
filein (RsConfigGetWildWestDir() + "script/3dsMax/_config_files/Wildwest_header.ms")
)
if (RsCollectToolUsageData != undefined) do
(
usagePath = (RsCollectToolUsageData filename versionNum:versionNum versionName:versionName)
)
)
)
)
)
-- Generates a banner-struct:
fn makeRsBanner dn_Panel:undefined colourScheme: wiki: mail: versionNum: versionName: width: doOutline:true doBottomLine:false trackUsage:true =
(
local newBanner = RsBannerStruct dn_Panel:dn_Panel doOutline:doOutline doBottomLine:doBottomLine trackUsage:trackUsage
if (colourScheme != unsupplied) do (newBanner.colourScheme = colourScheme)
if (wiki != unsupplied) do (newBanner.wiki = wiki)
if (mail != unsupplied) do (newBanner.mail = mail)
if (versionNum != unsupplied) do (newBanner.versionNum = versionNum)
if (versionName != unsupplied) do (newBanner.versionName = versionName)
if (width != unsupplied) do (newBanner.width = width)
return newBanner
)