Module:ProtoFlux: Difference between revisions

From Resonite Wiki
mNo edit summary
mNo edit summary
Line 30: Line 30:


function p.GenerateUI( frame )
function p.GenerateUI( frame )
  local inputsDecode = mw.text.jsonDecode( frame.args.Inputs );
-- Parse the JSON input, returning an empty array if no argument was passed
  local outputsDecode = mw.text.jsonDecode( frame.args.Outputs );
  local inputs = mw.text.jsonDecode( frame.args.Inputs or '[]' );
  local globalsDecode = mw.text.jsonDecode( frame.args.Globals );
  local outputs = mw.text.jsonDecode( frame.args.Outputs or '[]' );
  local globals = mw.text.jsonDecode( frame.args.Globals or '[]' );


  local protofluxContainer = mw.html.create( 'div' )
  local protofluxContainer = mw.html.create( 'div' )
Line 110: Line 111:


function createIOBindingPost(Container, Connector, isInput)
function createIOBindingPost(Container, Connector, isInput)
if nil and Connector and Connector.Type == "Impulse" then
  Container
    :tag( 'div' )
    :attr( 'rowspan', '2' )
    :cssText('background-color: black; border-style: none;')
    :tag( 'svg' )
      :attr( 'width', '38')
      :attr( 'height', '72')
      :cssText('display:block; stroke: rgba(179, 255, 255,1); fill: rgba(179, 255, 255,0.3); stroke-linejoin: round;')
      :tag( 'polygon' )
      :attr('style', 'stroke-width: 3px')
      :attr( 'points', '2,2 2,70, 36,36')
else
  Container
  Container
     :tag( 'div' )
     :tag( 'div' )
     :cssText('flex-grow: 1; background-color: ' .. getIOColor(Connector, 0.3) .. '; border: 5px solid ' .. getIOColor(Connector, 1.0) .. (isInput and '; border-left: none;' or ';border-right: none;'))
     :cssText('flex-grow: 1; background-color: ' .. getIOColor(Connector, 0.3) .. '; border: 5px solid ' .. getIOColor(Connector, 1.0) .. (isInput and '; border-left: none;' or ';border-right: none;'))
end
end
end



Revision as of 21:29, 13 January 2024

This is the Lua module for generating ProtoFlux UI elements on pages such as To String (ProtoFlux)

Please note, due to caching, updates made to this module will not immediately take effect on pages using it. If you need to see changes right away, use the editor view of a given page, which will update immediately.

Parameters

Name

Name of this ProtoFlux node. This should be the same as the name you see at the top of a given node in Resonite.

Category

Category for this ProtoFlux node. This is not the full category path, but only the direct parent - it should be the same as what appears at the bottom of a given node in Resonite.

Inline

Controls whether this node is displayed inline, or floats to the right. If this parameter is set, the node will draw inline, regardless of the value passed to it.

If you need content to flow below the element, use <div style="clear:right;"></div>, add the class .floatnone to an element, or use other elements with a similar CSS style tag.

Inputs

A string containing a JSON-encoded array of Name/Type information for each input on this node. Example input might be similar to the following, which adds two inputs of type String, one named Input1 and one named Input2

[{"Name":"Input1", "Type":"String"}, {"Name":"Input2", "Type":"String"}]

Outputs

A string containing a JSON-encoded array of Name/Type information for each output on this node. Example input might be similar to the following, which adds two outputs of type bool, one named Output1 and one named Output2

[{"Name":"Output1", "Type":"bool"}, {"Name":"Output2", "Type":"bool"}]

Globals

A string containing a JSON-encoded array of Name/Type information for each global on this node. Example input might be similar to the following, which adds two inputs of type User, one named Global1 and one named Global2

[{"Name":"Global1", "Type":"User"}, {"Name":"Global2", "Type":"User"}]

Custom

Either true or false (not case sensitive, defaults to false), if true the page is not added to ProtoFlux:All. This is mainly used for custom nodes.

Custom=false

Example Usage

If we combine all of the above examples together, we end up with this template invocation:

{{#Invoke:ProtoFlux|GenerateUI
|Name=Example Name
|Category=Example Category
|Inputs=
[
{"Name": "Input1", "Type": "Call"},
{"Name": "Input2", "Type": "String"}
]
|Outputs=
[
{"Name": "Output1", "Type": "bool"},
{"Name": "Output2", "Type": "bool"}
]
|Globals=
[
{"Name": "Global1", "Type": "User"},
{"Name": "Global2", "Type": "User"}
]
|}}

which results in the following:

Lua error at line 46: attempt to get length of global 'inputsDecode' (a nil value).


local p = {}

-- Type colors - RGB values to be included in the HTML output when a color is needed

local typeColor = 
{
 User = '255, 128, 255',
 Impulse = '179, 255, 255',
 Bool = '115, 115, 115',
 Boolean = '115, 115, 115',
 AsyncImpulse = '204, 179, 255',
 String = '245, 31, 31',
 Dummy = '255, 0, 255',
 IFormatProvider = '168, 143, 214',
 float = '0, 255, 255',
 ColorProfile = '255, 196, 54',
 colorX = '255, 89, 0',
 Component = '112, 76, 85',
 float3 = '0, 255, 255',
 float2 = '0, 255, 255'
}

-- Set the __index function of the metatable to return '0, 0, 0' - this effectively acts as the default value
-- if a type doesn't exist in the typeColor table.

local mt = {__index = function () return "0, 0, 0" end}
setmetatable(typeColor, mt)



function p.GenerateUI( frame )
 -- Parse the JSON input, returning an empty array if no argument was passed
 local inputs = mw.text.jsonDecode( frame.args.Inputs or '[]' );
 local outputs = mw.text.jsonDecode( frame.args.Outputs or '[]' );
 local globals = mw.text.jsonDecode( frame.args.Globals or '[]' );

 local protofluxContainer = mw.html.create( 'div' )
 
 protofluxContainer
  :cssText('color: white; background-color: #11151d; width: 256px; display: flex; flex-direction: column; align-items: stretch;' )
  :tag( 'div' )
  :cssText('padding: 10px 0px 10px 0px; text-align:center; font-weight: bold; background-color: #1a2a36; font-size: 18pt; flex-grow: 1;')
    :wikitext(frame.args.Name)
    :done()

 local maxRows = math.max(#inputsDecode, #outputsDecode)
 for i=1,maxRows do
  CreateIORow(protofluxContainer, inputsDecode[i], outputsDecode[i]);
 end
 
 for i=1,#globalsDecode do
	CreateGlobalsRow(protofluxContainer, globalsDecode[i]);
 end
 
protofluxContainer
 :tag( 'div' )
   :cssText( 'text-align: center; padding: 10px; font-size: 18pt; color: rgb(64,64,64); font-weight: bold;' )
   :wikitext(frame.args.Category)

 return tostring(protofluxContainer);

end
 
function CreateIORow(Container, Input, Output)
 local inputRow = Container
  :tag( 'div' )
  :cssText('display: flex; min-height: 70px;');
 createIOBindingPost(inputRow, Input, true);
 
inputRow
   :tag( 'div' ) -- The Input name
    :cssText( 'flex-grow: 2; display: flex; flex-direction: column; justify-content: space-between;')
    :tag( 'div' )
     :cssText('text-align: left; padding-left: 4px;  border-right: 20px solid #11151d; border-bottom: 4px solid #11151d; border-top: 4px solid #11151d; background-color:' .. getIOColor(Input, 0.6) .. ';')
     :wikitext( Input and Input.Name or ' ' )
	 :done()
	:tag( 'div')
     :cssText('text-align: right; padding-right: 4px; border-left: 20px solid #11151d; border-bottom: 4px solid #11151d; border-top: 4px solid #11151d; background-color: ' .. getIOColor(Output, 0.6) .. ';')
     :wikitext( Output and Output.Name or ' ' )
    : done()

createIOBindingPost(inputRow, Output, false);
   
end

-- Each Globlals row is really 2 rows high. 
function CreateGlobalsRow(Container, Global)
 local inputRow = Container
  :tag( 'div' )
     :cssText('display: flex; min-height: 70px; flex-direction: column; border-left: 10px solid ' .. getIOColor(Global, 1.0) .. ';')
	 :tag( 'div' ) -- The Input name
      :cssText('display: flex; flex-direction: row; align-items: center; flex-grow:1;')
	  :tag( 'span' )
	   :cssText('text-align: center; font-size: 14pt; font-weight: bold; flex-grow:1;')
       :wikitext( Global and Global.Name or ' ' )
	   :done()
	 :done()
	 :tag( 'div' )
      :attr('style', 'display:flex; gap: 10px; flex-grow: 1;')
      :tag('div')
	   :attr('style', 'border-radius: 16px; background-color: #777; font-style: italic; text-align:center; flex-grow: 3; display: flex; flex-direction: column; justify-content: center;')
        :tag( 'span' )
	    :wikitext( 'null' )
	    :done()
	   :done()
	  :tag( 'div')
      :attr('style', 'border-radius: 16px; background-color: #333; text-align:center; flex-grow: 1; display: flex; flex-direction: column; justify-content: center;')
       :tag ( 'span' )
	   :wikitext( '∅' )   
end

function createIOBindingPost(Container, Connector, isInput)
 Container
    :tag( 'div' )
     :cssText('flex-grow: 1; background-color: ' .. getIOColor(Connector, 0.3) .. '; border: 5px solid ' .. getIOColor(Connector, 1.0) .. (isInput and '; border-left: none;' or ';border-right: none;'))
end

function getIOColor(Connector, alpha)
 return (Connector and 'rgba(' .. typeColor[Connector.Type] .. ',' .. alpha .. ')' or 'rgba(0,0,0,0)')
end

return p