975 lines
24 KiB
Plaintext
Executable File
975 lines
24 KiB
Plaintext
Executable File
--
|
|
-- File:: pipeline/util/notenodes.ms
|
|
-- Description:: Common functions and globals for note node editing
|
|
--
|
|
-- Author:: Adam Munson <adam.munson@rockstarnorth.com>
|
|
-- Date:: 28/04/11
|
|
--
|
|
-----------------------------------------------------------------------------
|
|
global RsNoteNodeCallbackActive = false
|
|
unregisterRedrawViewsCallback RSnoteNodeRedrawCallback
|
|
|
|
global RsBugNodeAutoUpdate = true
|
|
global RsBugNodeAutoWarp = true
|
|
|
|
fn RSnoteNodeRedrawCallback =
|
|
(
|
|
::RSnoteNodeRedrawFunc()
|
|
)
|
|
|
|
struct RsNoteNodeSettingsStruct
|
|
(
|
|
coloursList = #(
|
|
Blue, -- Blue
|
|
Green, -- Green
|
|
(color 128 0 128), -- Purple
|
|
Yellow, -- Yellow
|
|
Orange, -- Orange
|
|
Brown, -- Brown
|
|
Black -- Black
|
|
),
|
|
|
|
typeNames = #(
|
|
"Point",
|
|
"Link (Start)",
|
|
"Box (Start)",
|
|
"Arrow (Start)",
|
|
"P_Standing"
|
|
),
|
|
|
|
fn getBugColour bugClass =
|
|
(
|
|
case bugClass of
|
|
(
|
|
"A":(red)
|
|
"B":(yellow)
|
|
"C":(orange)
|
|
"D":(brown)
|
|
"TASK":(blue)
|
|
"TODO":(green)
|
|
default:(red + blue)
|
|
)
|
|
),
|
|
|
|
type_point = 1,
|
|
type_link = 2,
|
|
type_box = 3,
|
|
type_arrow = 4,
|
|
type_scalejaxx = 5,
|
|
|
|
setTotal = 5,
|
|
nodeTotal = 90,
|
|
textLength = 255, -- 255 to allow for /0 in game
|
|
|
|
humanMesh,
|
|
selPointMesh,
|
|
bugMesh,
|
|
defaultNode = (createInstance ::RsNoteNode)
|
|
)
|
|
|
|
global RsNoteNodeSettings
|
|
global RsNoteNodeGroup -- Array to store all the sets and nodes from one notenode xml file
|
|
global RsNoteNodeSet
|
|
global RsNoteNodeNum
|
|
global RsNoteNodeCreateLink
|
|
global RsNoteNodeImporting
|
|
|
|
--
|
|
-- fn: RsNoteNodesResetGlobals
|
|
-- desc:Resets the globals used, to default values
|
|
--
|
|
fn RsNoteNodesResetGlobals =
|
|
(
|
|
RsNoteNodeSettings = RsNoteNodeSettingsStruct()
|
|
|
|
-- Set defaultNode to allow access to node's default params:
|
|
RsNoteNodeSettings.defaultNode = createInstance RsNoteNode
|
|
|
|
RsNoteNodeGroup = #()
|
|
for s = 1 to RsNoteNodeSettings.setTotal do
|
|
(
|
|
append RsNoteNodeGroup #()
|
|
)
|
|
RsNoteNodeSet = 1
|
|
RsNoteNodeNum = 1
|
|
RsNoteNodeCreateLink = false
|
|
RsNoteNodeImporting = false
|
|
)
|
|
|
|
--
|
|
-- fn RsNoteNodeCheckIfGroupExists
|
|
-- desc Checks to see if a populated node group exists
|
|
--
|
|
fn RsNoteNodeCheckIfGroupExists =
|
|
(
|
|
local retVal = false
|
|
|
|
if (RsNoteNodeGroup != undefined) do
|
|
(
|
|
for grp in RsNoteNodeGroup while not retVal do
|
|
(
|
|
for item in grp where (item != undefined) while not retVal do
|
|
(
|
|
retVal = true
|
|
)
|
|
)
|
|
)
|
|
|
|
return retVal
|
|
)
|
|
|
|
--
|
|
-- fn: RsNoteNodesDeleteGroup
|
|
-- desc:Deletes any note nodes currently loaded and resets array
|
|
--
|
|
fn RsNoteNodesDeleteGroup =
|
|
(
|
|
clearSelection()
|
|
|
|
-- Delete the old note node group if one is previously loaded
|
|
if ( true == RsNoteNodeCheckIfGroupExists() ) do
|
|
(
|
|
for s = RsNoteNodeGroup.count to 1 by -1 do
|
|
(
|
|
for nn = RsNoteNodeGroup[s].count to 1 by -1 do
|
|
(
|
|
if ( RsNoteNodeGroup[s][nn] != undefined ) do
|
|
(
|
|
if ( isValidNode RsNoteNodeGroup[s][nn] ) do
|
|
(
|
|
delete RsNoteNodeGroup[s][nn]
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
RsNoteNodesResetGlobals()
|
|
::RsNoteNodesFilterRoll.RsUpdateBlocksList()
|
|
::RsNoteNodesSetRoll.spnSetNumber.value = RsNoteNodeSet
|
|
)
|
|
|
|
--------------------------------
|
|
-- NOTE-NODE OBJECT --
|
|
--------------------------------
|
|
plugin helper RsNoteNode
|
|
name:"RsNoteNode"
|
|
category:"RS Utils"
|
|
replaceUI:true
|
|
extends:dummy
|
|
classID:#(0x59c69cf3, 0x589eabdc)
|
|
(
|
|
local meshObj, isBugDelegate
|
|
|
|
parameters main rollout:params
|
|
(
|
|
nodeLabel type:#string default:"Node"
|
|
|
|
nodeLink type:#node ui:btnLinkPick
|
|
|
|
nodeType type:#integer default:1 ui:lstNodeType
|
|
nodeSize type:#worldUnits default:1.65 ui:spnNodeSize
|
|
colourIdx type:#integer default:1
|
|
blockName type:#string default:""
|
|
|
|
setNumber type:#integer default:-1
|
|
nodeNumber type:#integer default:-1
|
|
)
|
|
|
|
rollout params "Note Node"
|
|
(
|
|
editText txtLabel "" labelOnTop:true width:156 offset:[-10,0]
|
|
dotNetControl txtData "MaxCustomControls.MaxTextBox" width:txtLabel.width height:100 pos:(txtLabel.pos.x + [0, 21])
|
|
|
|
local clrBtnSize = 19
|
|
|
|
label clrLbl "Colour:" align:#left offset:[0,-3]
|
|
checkButton clrBtn1 "" width:clrBtnSize height:clrBtnSize across:7
|
|
checkButton clrBtn2 "" width:clrBtnSize height:clrBtnSize
|
|
checkButton clrBtn3 "" width:clrBtnSize height:clrBtnSize
|
|
checkButton clrBtn4 "" width:clrBtnSize height:clrBtnSize
|
|
checkButton clrBtn5 "" width:clrBtnSize height:clrBtnSize
|
|
checkButton clrBtn6 "" width:clrBtnSize height:clrBtnSize
|
|
checkButton clrBtn7 "" width:clrBtnSize height:clrBtnSize
|
|
|
|
local clrBtns = #(clrBtn1, clrBtn2, clrBtn3, clrBtn4, clrBtn5, clrBtn6, clrBtn7)
|
|
|
|
listbox lstNodeType "Type:" items:RsNoteNodeSettings.typeNames height:RsNoteNodeSettings.typeNames.count
|
|
|
|
spinner spnNodeSize "Size (Radius):" range:[0.5, 100, 0]
|
|
|
|
fn pickFilter obj =
|
|
(
|
|
-- Don't allow dependency loops:
|
|
(isKindOf obj RsNoteNode) and (not refs.dependencyLoopTest obj (refs.dependentNodes This)[1])
|
|
)
|
|
|
|
groupBox grpLinks "Node Links:" width:152 height:110 offset:[-8,0]
|
|
label lblLinkPick "Linked to:" align:#left offset:[0, -grpLinks.height + 13]
|
|
pickButton btnLinkPick "None" autoDisplay:true width:140 offset:[-1,0] tooltip:"Rightclick to clear"
|
|
label lblLinkShow "" width:140 height:46 align:#left
|
|
|
|
fn setNoteText newText =
|
|
(
|
|
if (newText == "") then
|
|
(
|
|
txtData.visible = false
|
|
txtData.pos.y -= 400 -- Move control up out of the way, as it can interfere with clicking even when hidden
|
|
|
|
for n = ((findItem params.controls txtData) + 1) to params.controls.count do
|
|
(
|
|
params.controls[n].pos.y -= txtData.height
|
|
)
|
|
|
|
-- Set rollout size, if need be:
|
|
local lastCtrl = params.controls[params.controls.count]
|
|
local newHeight = lastCtrl.pos.y + 54
|
|
if params.height != newHeight do params.height = newHeight
|
|
)
|
|
else
|
|
(
|
|
if (not txtData.visible) do
|
|
(
|
|
txtData.visible = true
|
|
for n = ((findItem params.controls txtData) + 1) to params.controls.count do
|
|
(
|
|
params.controls[n].pos.y += txtData.height
|
|
)
|
|
params.height += txtData.height
|
|
)
|
|
|
|
-- DotNet textbox needs \r as well as \n for newlines:
|
|
txtData.text = replace_LF_with_CRLF newText
|
|
)
|
|
)
|
|
|
|
fn updateCtrls =
|
|
(
|
|
local showText = stringstream ""
|
|
|
|
-- Show any non-default node-settings:
|
|
if (blockName != "") do
|
|
(
|
|
format "blockName: %\n" blockName to:showText
|
|
)
|
|
if (nodeNumber != -1) do
|
|
(
|
|
format "nodeNumber: %\n" nodeNumber to:showText
|
|
)
|
|
if (setNumber != -1) do
|
|
(
|
|
format "setNumber: %\n" setNumber to:showText
|
|
)
|
|
if (filePos showText != 0) do
|
|
(
|
|
format "\n" nodeText to:showText
|
|
)
|
|
|
|
setNoteText (showText as string)
|
|
|
|
-- Update link-label:
|
|
local newText = "Linked from "
|
|
|
|
local foundLink = false
|
|
|
|
local thisNode = (refs.dependentNodes This)[1]
|
|
|
|
if (thisNode != undefined) do
|
|
(
|
|
local nodeDeps = for obj in (refs.dependentNodes thisNode) where (isKindOf obj RsNoteNode) collect obj
|
|
|
|
if (nodeDeps.count != 0) do
|
|
(
|
|
foundLink = true
|
|
append newText (nodeDeps.count as string + " nodes:\n")
|
|
|
|
for dep in nodeDeps do
|
|
(
|
|
append newText (dep.name + "\n")
|
|
)
|
|
)
|
|
)
|
|
|
|
if not foundLink do
|
|
(
|
|
append newText "0 nodes"
|
|
)
|
|
|
|
lblLinkShow.text = newText
|
|
)
|
|
|
|
on lstNodeType selected num do
|
|
(
|
|
meshObj = undefined
|
|
)
|
|
|
|
on spnNodeSize changed val do
|
|
(
|
|
meshObj = undefined
|
|
--delegate.size = nodeSize * 0.5
|
|
)
|
|
|
|
-- Clear link-node on rightclick
|
|
on btnLinkPick rightclick do
|
|
(
|
|
nodeLink = undefined
|
|
)
|
|
|
|
fn pressedClrBtn num =
|
|
(
|
|
undo "change node colour" on
|
|
(
|
|
clrBtns.checked = false
|
|
clrBtns[num].checked = true
|
|
colourIdx = num
|
|
)
|
|
)
|
|
|
|
on clrBtn1 changed state do (pressedClrBtn 1)
|
|
on clrBtn2 changed state do (pressedClrBtn 2)
|
|
on clrBtn3 changed state do (pressedClrBtn 3)
|
|
on clrBtn4 changed state do (pressedClrBtn 4)
|
|
on clrBtn5 changed state do (pressedClrBtn 5)
|
|
on clrBtn6 changed state do (pressedClrBtn 6)
|
|
on clrBtn7 changed state do (pressedClrBtn 7)
|
|
|
|
on txtLabel changed newText do
|
|
(
|
|
if (newText.count > RsNoteNodeSettings.textLength) do
|
|
(
|
|
newText = substring newText 1 RsNoteNodeSettings.textLength
|
|
txtLabel.text = newText
|
|
nodeLabel = newText
|
|
|
|
messageBox ("Entered text was bigger than " + (RsNoteNodeSettings.textLength as string) + " characters, the end has been removed") title:"Label too long"
|
|
)
|
|
)
|
|
|
|
on txtLabel entered newText do
|
|
(
|
|
undo "change node name" on
|
|
(
|
|
nodeLabel = newText
|
|
)
|
|
)
|
|
|
|
on params open do
|
|
(
|
|
txtLabel.text = nodeLabel
|
|
|
|
-- Set up dotNet textbox (which allows for easy wordwrapping)
|
|
local textClr = (colorMan.getColor #windowText) * 255
|
|
local windowClr = (colorMan.getColor #window) * 255
|
|
txtData.foreColor = (dotNetClass "System.Drawing.Color").FromArgb textClr[1] textClr[2] textClr[3]
|
|
txtData.backColor = (dotNetClass "System.Drawing.Color").FromArgb windowClr[1] windowClr[2] windowClr[3]
|
|
|
|
txtData.readOnly = true
|
|
txtData.multiline = true
|
|
txtData.scrollbars = txtData.ScrollBars.vertical
|
|
txtData.wordWrap = true
|
|
txtData.SelectionStart = 0
|
|
txtData.SelectionLength = 0
|
|
txtData.readonly = true
|
|
|
|
-- Paint the colour-buttons:
|
|
local blankBmp = bitmap clrBtnSize clrBtnSize
|
|
local clrList = RsNoteNodeSettings.coloursList
|
|
local clrSize = clrBtnSize - 4
|
|
|
|
for n = 1 to clrBtns.count do
|
|
(
|
|
clrBtns[n].images = #(bitmap clrSize clrSize color:clrList[n], blankBmp, 1,1,1,1,1)
|
|
)
|
|
|
|
clrBtns[colourIdx].checked = true
|
|
|
|
updateCtrls()
|
|
)
|
|
)
|
|
|
|
-- Don't allow instancing, as it buggers up path-drawing:
|
|
fn deInstance =
|
|
(
|
|
local deps = refs.dependentNodes This
|
|
if (deps.count > 1) do
|
|
(
|
|
InstanceMgr.MakeObjectsUnique deps #individual
|
|
)
|
|
)
|
|
|
|
on update do
|
|
(
|
|
deInstance()
|
|
meshObj = undefined
|
|
isBugDelegate = undefined
|
|
|
|
-- Change something in the paramblock to force a redraw
|
|
nodeLabel = nodeLabel
|
|
)
|
|
|
|
on detachedFromNode nodeToDelete do
|
|
(
|
|
-- Callback for when a node is deleted from the scene. We have to
|
|
-- go through all the nodes to check if there is a link to the node
|
|
-- and if so, remove that but then also shift down all the indexes to nodes
|
|
-- after it in the array
|
|
if ( RsNoteNodeGroup != undefined ) do
|
|
(
|
|
if ( true == RsNoteNodeCheckIfGroupExists() ) do
|
|
(
|
|
nodeIdx = -1
|
|
|
|
for nn = 1 to RsNoteNodeGroup[setNumber].count do
|
|
(
|
|
if ( RsNoteNodeGroup[setNumber][nn] == nodeToDelete ) do
|
|
(
|
|
nodeIdx = nn
|
|
)
|
|
)
|
|
|
|
-- Remove node from array, shrinking it
|
|
Assert ( nodeIdx > 0 ) message:"nodeIdx is not above 0 in RsNoteNodesDeleteNode"
|
|
deleteitem RsNoteNodeGroup[setNumber] nodeIdx
|
|
if ( 1 != RsNoteNodeNum ) do
|
|
(
|
|
RsNoteNodeNum -= 1
|
|
)
|
|
)
|
|
)
|
|
)
|
|
|
|
on attachedToNode newNode do
|
|
(
|
|
-- Check global to make sure we're not in middle of importing
|
|
-- as we don't need to do this with
|
|
if ((isKindOf newNode RsNoteNode) and (RsNoteNodeImporting == false)) do
|
|
(
|
|
if (RsNoteNodesUtil != undefined) and RsNoteNodesUtil.open and (RsNoteNodeGroup != undefined) and (RsNoteNodeNum != undefined) do
|
|
(
|
|
if ( RsNoteNodeNum <= RsNoteNodeSettings.nodeTotal ) then
|
|
(
|
|
newNode.setNumber = RsNoteNodeSet
|
|
newNode.nodeNumber = RsNoteNodeNum
|
|
append RsNoteNodeGroup[RsNoteNodeSet] newNode
|
|
--format "Set:%\tNodeNum:%\n" newNode.setNumber newNode.nodeNumber
|
|
RsNoteNodeNum += 1
|
|
)
|
|
else
|
|
(
|
|
Messagebox ( "This set is full (" + ( RsNoteNodeSettings.nodeTotal as string ) + \
|
|
"), you cannot make any more nodes unless you delete some" )
|
|
)
|
|
)
|
|
)
|
|
)
|
|
|
|
on getDisplayMesh do
|
|
(
|
|
deInstance()
|
|
|
|
local thisNode = (refs.dependentNodes this)[1]
|
|
if (isBugDelegate == undefined) do (isBugDelegate = (isKindOf thisNode ::RsBugNode))
|
|
|
|
local showMesh
|
|
local nodeColour = thisNode.wirecolor
|
|
|
|
if (RsNoteNodeSettings.selPointMesh == undefined) do
|
|
(
|
|
local newMesh = (createInstance Plane).mesh
|
|
local selSize = 0.01
|
|
setMesh newMesh vertices:#([-selSize,-selSize,0], [selSize,-selSize,0], [selSize,selSize,0],[-selSize,selSize,0]) faces:#([1,2,3], [2,3,4])
|
|
|
|
for faceNum = 1 to 2 do
|
|
(
|
|
for edgeNum = 1 to 2 do
|
|
(
|
|
setEdgeVis newMesh faceNum edgeNum false
|
|
)
|
|
)
|
|
|
|
RsNoteNodeSettings.selPointMesh = newMesh
|
|
)
|
|
|
|
if isBugDelegate then
|
|
(
|
|
-- Set bug-colours:
|
|
nodeColour = RsNoteNodeSettings.getBugColour thisNode.bugClass
|
|
|
|
-- Set bug-mesh:
|
|
if (RsNoteNodeSettings.bugMesh == undefined) do
|
|
(
|
|
RsNoteNodeSettings.bugMesh = manip.makeSphere [0,0,0] 4.0 4
|
|
|
|
meshOp.attach RsNoteNodeSettings.bugMesh RsNoteNodeSettings.selPointMesh
|
|
)
|
|
|
|
showMesh = RsNoteNodeSettings.bugMesh
|
|
)
|
|
else
|
|
(
|
|
-- Get node-colour by index:
|
|
nodeColour = RsNoteNodeSettings.coloursList[this.colourIdx]
|
|
|
|
-- Draw appropriate mesh/marker for node-type:
|
|
case this.nodeType of
|
|
(
|
|
(RsNoteNodeSettings.type_point):
|
|
(
|
|
showMesh = RsNoteNodeSettings.selPointMesh
|
|
)
|
|
(RsNoteNodeSettings.type_link):
|
|
(
|
|
if (meshObj == undefined) do
|
|
(
|
|
meshObj = manip.makeSphere [0,0,0] nodeSize 8
|
|
meshOp.attach meshObj RsNoteNodeSettings.selPointMesh
|
|
)
|
|
showMesh = meshObj
|
|
)
|
|
(RsNoteNodeSettings.type_arrow):
|
|
(
|
|
if (meshObj == undefined) do
|
|
(
|
|
meshObj = manip.makeSphere [0,0,0] nodeSize 8
|
|
meshOp.attach meshObj RsNoteNodeSettings.selPointMesh
|
|
)
|
|
showMesh = meshObj
|
|
)
|
|
(RsNoteNodeSettings.type_box):
|
|
(
|
|
drawLink = false
|
|
|
|
if (nodeLink != undefined) and (isValidNode nodeLink) then
|
|
(
|
|
local posDiff = nodeLink.pos - thisNode.pos
|
|
showMesh = manip.makeBox (0.5 * posDiff) posDiff.y posDiff.x posDiff.z 1 1 1
|
|
|
|
-- Box resists node-rotation:
|
|
rotate showMesh thisNode.rotation
|
|
)
|
|
else
|
|
(
|
|
showMesh = RsNoteNodeSettings.selPointMesh
|
|
)
|
|
)
|
|
(RsNoteNodeSettings.type_scalejaxx):
|
|
(
|
|
if (RsNoteNodeSettings.humanMesh == undefined) do
|
|
(
|
|
RsNoteNodeSettings.humanMesh = (createInstance ::P_Standing).mesh
|
|
meshOp.attach RsNoteNodeSettings.humanMesh RsNoteNodeSettings.selPointMesh
|
|
)
|
|
showMesh = RsNoteNodeSettings.humanMesh
|
|
)
|
|
default:
|
|
(
|
|
if (meshObj == undefined) do
|
|
(
|
|
meshObj = manip.makeSphere [0,0,0] nodeSize 4
|
|
|
|
meshOp.attach meshObj RsNoteNodeSettings.selPointMesh
|
|
)
|
|
showMesh = meshObj
|
|
)
|
|
)
|
|
)
|
|
|
|
-- Set node-colours:
|
|
if (thisNode.wirecolor != nodeColour) do
|
|
(
|
|
thisNode.wirecolor = nodeColour
|
|
)
|
|
|
|
-- Start up the redraw callback, if it's not already active:
|
|
if not RsNoteNodeCallbackActive do
|
|
(
|
|
RsNoteNodeCallbackActive = true
|
|
unregisterRedrawViewsCallback RSnoteNodeRedrawCallback
|
|
registerRedrawViewsCallback RSnoteNodeRedrawCallback
|
|
)
|
|
|
|
return showMesh
|
|
)
|
|
|
|
tool create
|
|
(
|
|
on mousePoint click do
|
|
(
|
|
nodeTM.translation = gridPoint
|
|
|
|
#stop
|
|
)
|
|
) -- tool create
|
|
)
|
|
|
|
------------------------------
|
|
-- BUG-NODE OBJECT --
|
|
------------------------------
|
|
plugin helper RsBugNode
|
|
name:"RsBugNode"
|
|
category:"RS Utils"
|
|
classID:#(0x56816126, 0x67f4c0d3)
|
|
extends:RsNoteNode
|
|
autoPromoteDelegateProps:true
|
|
replaceUI:true
|
|
(
|
|
parameters main rollout:params
|
|
(
|
|
nodeText type:#string default:""
|
|
|
|
bugId type:#string default:""
|
|
bugClass type:#string default:""
|
|
bugComponent type:#string default:""
|
|
bugSummary type:#string default:""
|
|
tagList type:#stringTab animatable:false tabSizeVariable:true
|
|
)
|
|
|
|
-- Used to store bug-edits, for deferred server-submit:
|
|
local pendingChanges
|
|
|
|
fn setNodeLabel =
|
|
(
|
|
local newLabel = bugClass + ": " + bugId
|
|
|
|
if (delegate.nodelabel != newLabel) do
|
|
(
|
|
delegate.nodelabel = newLabel
|
|
)
|
|
)
|
|
|
|
fn selNextPrev prev:true justEdited:false =
|
|
(
|
|
local bugNodes = for obj in helpers where (isKindOf obj RsBugNode) and ((not justEdited) or (obj.pendingChanges != undefined)) collect obj
|
|
local thisNodeNum = findItem bugNodes $
|
|
|
|
local increment = if prev then -1 else 1
|
|
local selNum = thisNodeNum + increment
|
|
|
|
case of
|
|
(
|
|
(selNum < 1):(selNum = bugNodes.count)
|
|
(selNum > bugNodes.count):(selNum = 1)
|
|
)
|
|
|
|
select bugNodes[selNum]
|
|
DisableSceneRedraw()
|
|
HelpersVisibilityState = HideByCategory.Helpers
|
|
HideByCategory.Helpers = false
|
|
max tool zoomextents
|
|
HideByCategory.Helpers = HelpersVisibilityState
|
|
EnableSceneRedraw()
|
|
select bugNodes[selNum]
|
|
)
|
|
|
|
rollout params "Bug Node"
|
|
(
|
|
local ctrlWidth = 154
|
|
local halfWidth = (ctrlWidth / 2 - 2)
|
|
|
|
button btnBugToolkit "Max Bugstar Toolkit" width:ctrlWidth offset:[-1,-2]
|
|
|
|
button btnSelPrevBug "<- Prev Bug" width:halfWidth offset:[-7,0] across:2
|
|
button btnSelNextBug "Next Bug ->" width:halfWidth offset:[4,0]
|
|
|
|
--button btnEditBug "Edit Bug" offset:[-10,0] width:halfWidth align:#left across:2 tooltip:"Make changes to bug on server"
|
|
button btnCommitPending "Submit Edits" enabled:false tooltip:"Submit pending bug-edits to server" width:ctrlWidth
|
|
|
|
checkbutton chkbtnWarpPlayer "Auto Warp Player to location" align:#left offset:[-10,0] height:18 checked:RsBugNodeAutoWarp
|
|
|
|
button btnOpenClient "Show in Bugstar Client" width:ctrlWidth offset:[-2,0]
|
|
|
|
button btnUpdate "Update BugNode" align:#left offset:[-10,0] height:18 across:2
|
|
checkbox chkAutoUpdate "Auto" offset:[3,2] align:#right checked:RsBugNodeAutoUpdate
|
|
|
|
dotNetControl txtData "MaxCustomControls.MaxTextBox" width:ctrlWidth height:300 offset:[-10,0]
|
|
|
|
fn setNoteText newText =
|
|
(
|
|
txtData.text = replace_LF_with_CRLF (RsWordWrap newText 130)
|
|
)
|
|
|
|
fn updateCtrls =
|
|
(
|
|
btnOpenClient.enabled = (bugId != "")
|
|
setNoteText nodeText
|
|
|
|
local pendingCount = 0
|
|
for obj in helpers where (isKindOf obj RsBugNode) and (obj.pendingChanges != undefined) do
|
|
(
|
|
pendingCount += 1
|
|
)
|
|
|
|
btnCommitPending.enabled = (pendingCount != 0)
|
|
)
|
|
|
|
on btnSelPrevBug pressed do
|
|
(
|
|
selNextPrev prev:true
|
|
)
|
|
|
|
on btnSelNextBug pressed do
|
|
(
|
|
selNextPrev prev:false
|
|
)
|
|
|
|
on btnOpenClient pressed do
|
|
(
|
|
::bugstar.openBugInClient bugId
|
|
)
|
|
|
|
fn updateBug =
|
|
(
|
|
local selObj = $
|
|
local rememberPos = selObj.pos
|
|
|
|
if (::bugstar == undefined) do
|
|
(
|
|
fileIn "pipeline/helpers/debug/bugstar.ms"
|
|
)
|
|
|
|
local bugdata = bugstar.getBug bugId
|
|
|
|
-- Turn off auto-update if login failed:
|
|
if not bugstar.hasValidPassword() do
|
|
(
|
|
RsBugNodeAutoUpdate = chkAutoUpdate.checked = false
|
|
return false
|
|
)
|
|
|
|
bugstar.updateBugNode selObj bugdata
|
|
|
|
-- Don't move object if it's over origin, as those will have been raised up on purpose:
|
|
if (selObj.pos != rememberPos) and (not (rememberPos.x == rememberPos.y == 0)) do
|
|
(
|
|
selObj.pos = rememberPos
|
|
)
|
|
|
|
updateCtrls()
|
|
)
|
|
|
|
fn warpPlayer =
|
|
(
|
|
local selObj = $
|
|
::RsRagFuncs.setPlayerPos selObj.pos dir:(selObj.rotation as eulerangles).z
|
|
)
|
|
|
|
/*
|
|
on btnEditBug pressed do
|
|
(
|
|
if (::bugstar == undefined) do
|
|
(
|
|
fileIn "pipeline/helpers/debug/bugstar.ms"
|
|
)
|
|
if (::RsBugstarEditDialog == undefined) do
|
|
(
|
|
fileIn "pipeline/helpers/debug/bugstar_edit.ms"
|
|
)
|
|
|
|
::RsBugstarEditDialog.createRoll()
|
|
)
|
|
*/
|
|
on btnUpdate pressed do
|
|
(
|
|
updateBug()
|
|
)
|
|
|
|
on chkAutoUpdate changed val do
|
|
(
|
|
RsBugNodeAutoUpdate = val
|
|
if val do updateBug()
|
|
)
|
|
|
|
on chkbtnWarpPlayer changed val do
|
|
(
|
|
RsBugNodeAutoWarp = val; if val do warpPlayer();
|
|
)
|
|
|
|
|
|
|
|
on btnBugToolkit pressed do
|
|
(
|
|
filein "pipeline/helpers/debug/bugstar_ui.ms"
|
|
)
|
|
|
|
on params open do
|
|
(
|
|
--Lets load in the relevant fileins instead of checking everytime we run a callback on a button press --
|
|
if (::RsRagFuncs == undefined) do
|
|
fileIn "pipeline/util/RAG_funcs.ms";
|
|
|
|
-- Set up dotNet textbox (which allows for easy wordwrapping)
|
|
local textClr = (colorMan.getColor #windowText) * 255
|
|
local windowClr = (colorMan.getColor #window) * 255
|
|
|
|
txtData.foreColor = (dotNetClass "System.Drawing.Color").FromArgb textClr[1] textClr[2] textClr[3]
|
|
txtData.backColor = (dotNetClass "System.Drawing.Color").FromArgb windowClr[1] windowClr[2] windowClr[3]
|
|
|
|
txtData.readOnly = true
|
|
txtData.multiline = true
|
|
txtData.scrollbars = txtData.ScrollBars.vertical
|
|
txtData.wordWrap = true
|
|
txtData.SelectionStart = 0
|
|
txtData.SelectionLength = 0
|
|
txtData.readonly = true
|
|
|
|
if RsBugNodeAutoUpdate then updateBug() else updateCtrls()
|
|
-- If auto Warp on then letes warp
|
|
if RsBugNodeAutoWarp then warpPlayer()
|
|
)
|
|
|
|
on params rolledUp val do
|
|
(
|
|
if val do
|
|
(
|
|
updateCtrls()
|
|
)
|
|
)
|
|
)
|
|
|
|
on update do
|
|
(
|
|
setNodeLabel()
|
|
)
|
|
)
|
|
|
|
-- This redraw-callback function draws the node-text and links:
|
|
fn RSnoteNodeRedrawFunc =
|
|
(
|
|
local noteObjs = for obj in objects where (not obj.isHidden) and ((isKindOf obj RsNoteNode) or (isKindOf obj RsBugNode)) collect obj
|
|
|
|
if (noteObjs.count != 0) do
|
|
(
|
|
local lineLenth = 300
|
|
local arrowSize = 10
|
|
|
|
local rndLimits = gw.getRndLimits()
|
|
local zBufNum = findItem rndLimits #zBuffer
|
|
if (zBufNum != 0) do (deleteItem rndLimits zBufNum)
|
|
gw.setRndLimits rndLimits
|
|
|
|
gw.setTransform (Matrix3 1)
|
|
|
|
for obj in noteObjs do
|
|
(
|
|
local isBug = isKindOf obj RsBugNode
|
|
|
|
local nodeLabel = obj.nodeLabel
|
|
local nodeLink = obj.nodeLink
|
|
|
|
local hasText = (nodeLabel != "")
|
|
local hasLink = (isValidNode nodeLink)
|
|
|
|
if isBug or hasText or hasLink do
|
|
(
|
|
local manipColour, textColour
|
|
|
|
if obj.isSelected then
|
|
(
|
|
manipColour = textColour = white
|
|
)
|
|
else
|
|
(
|
|
manipColour = obj.wirecolor
|
|
)
|
|
|
|
local labelPos = gw.wtransPoint obj.pos
|
|
|
|
local showMesh, showMarker
|
|
local drawLink = true
|
|
|
|
-- Draw appropriate mesh/marker for node-type:
|
|
if isBug then
|
|
(
|
|
-- Bugs show asterisk marker:
|
|
showMarker = #asterisk
|
|
)
|
|
else
|
|
(
|
|
case obj.nodeType of
|
|
(
|
|
(RsNoteNodeSettings.type_point):
|
|
(
|
|
showMarker = #xMarker
|
|
)
|
|
(RsNoteNodeSettings.type_link):
|
|
(
|
|
showMarker = #circle
|
|
)
|
|
(RsNoteNodeSettings.type_arrow):
|
|
(
|
|
directionMesh = true
|
|
showMarker = #triangle
|
|
)
|
|
(RsNoteNodeSettings.type_box):
|
|
(
|
|
drawLink = false
|
|
showMarker = #hollowBox
|
|
)
|
|
(RsNoteNodeSettings.type_scalejaxx):
|
|
(
|
|
showMarker = #circle
|
|
)
|
|
default:
|
|
(
|
|
showMarker = #circle
|
|
)
|
|
)
|
|
)
|
|
|
|
-- Draw line to nodeLink node:
|
|
if drawLink and hasLink do
|
|
(
|
|
gw.setColor #line manipColour
|
|
|
|
local startPoint = labelPos
|
|
local endPoint = gw.wtransPoint nodeLink.pos
|
|
|
|
local LineVector = endPoint - startPoint
|
|
LineVector.z = 0
|
|
|
|
local LineNorm = normalize LineVector
|
|
local PerpNorm = normalize [LineVector.y,-LineVector.x,0]
|
|
|
|
local scaledLineNorm = (arrowSize * LineNorm)
|
|
local scaledPerpNorm = (arrowSize * PerpNorm * 0.5)
|
|
|
|
gw.wPolyline #(startPoint, endPoint - scaledLineNorm) false
|
|
|
|
gw.wPolyline #((endPoint - scaledLineNorm - scaledPerpNorm), endPoint, (endPoint - scaledLineNorm + scaledPerpNorm)) true
|
|
)
|
|
|
|
if (showMarker != undefined) do
|
|
(
|
|
gw.wMarker labelPos showMarker color:manipColour
|
|
)
|
|
|
|
-- Draw node-label text:
|
|
if hasText do
|
|
(
|
|
-- Make text slightly lighter than mesh:
|
|
local textColour = manipColour + 70
|
|
if (textColour.r > 255) do (textColour.r = 255)
|
|
if (textColour.g > 255) do (textColour.g = 255)
|
|
if (textColour.b > 255) do (textColour.b = 255)
|
|
|
|
/*
|
|
local newText = RsWordWrap nodeLabel lineLenth
|
|
local labelLines = filterString newText "\n"
|
|
*/
|
|
local labelLines = #(nodeLabel)
|
|
|
|
for n = labelLines.count to 1 by -1 do
|
|
(
|
|
gw.wtext labelPos labelLines[n] color:textColour
|
|
|
|
labelPos -= [0, 13, 0]
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
|
|
RsNoteNodesResetGlobals()
|
|
|
|
RSnoteNodeRedrawCallback()
|