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:¤tKey ) 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 )