Skip to content

Instantly share code, notes, and snippets.

@AndrewHazelden
Created November 27, 2024 22:01
Show Gist options
  • Save AndrewHazelden/8894bbfe629014dae02dfdd410bebb46 to your computer and use it in GitHub Desktop.
Save AndrewHazelden/8894bbfe629014dae02dfdd410bebb46 to your computer and use it in GitHub Desktop.
Inserts a new sMerge node and auto-connects the selected nodes as input connections.
--[[--
sMerge Selected - 2024-10-25 12.50 PM
By Andrew Hazelden ([email protected])
Overview:
Inserts a new sMerge node and auto-connects the selected nodes as input connections.
Installation:
Copy the "sMerge Selected.lua" script to the "Scripts:/Comp" PathMap folder.
Usage:
1. Select several nodes in the flow area.
2. Launch the "Scripts > sMerge Selected" menu item.
3. In the "sMerge Selected" window use the Sort Order control to choose if you would like to sort the node connections by "Vertical Position", "Horizontal Position", or "Node Name". Click the OK button to continue.
4. The script will add a new sMerge node. The selected nodes in the flow area will be automatically connected to the sMerge node input connections.
Known Issue:
Using a Fusion window layout that doesn't use a flow area on the main monitor can result in an error message of:
This script can't find the Fusion flow view. Try using a single monitor layout if you want to sort the node input connections by "Vertical Position" or "Horizontal Position".
--]]--
-------------------------------------------------------------------------------
-- Read a fusion specific preference value. If nothing exists set and return a default value
-- Example: splitDirection = getPreferenceData("sMrgSelected.sort", 1, true)
function getPreferenceData(pref, defaultValue, debugPrint)
-- Choose if you are saving the preference to the comp or to all of fusion
-- local newPreference = comp:GetData(pref)
local newPreference = fu:GetData(pref)
if newPreference ~= nil then
-- List the existing preference value
if (debugPrint == true) or (debugPrint == 1) then
if newPreference == nil then
print("[Reading " .. tostring(pref) .. " Preference Data] " .. "nil")
else
print("[Reading " .. tostring(pref) .. " Preference Data] " .. tostring(newPreference))
end
end
else
-- Force a default value into the preference & then list it
newPreference = defaultValue
-- Choose if you are saving the preference to the comp or to all of fusion
-- comp:SetData(pref, defaultValue)
fu:SetData(pref, defaultValue)
if (debugPrint == true) or (debugPrint == 1) then
if newPreference == nil then
print("[Creating " .. tostring(pref) .. " Preference Data] " .. "nil")
else
print("[Creating ".. tostring(pref) .. " Preference Entry] " .. tostring(newPreference))
end
end
end
return newPreference
end
-------------------------------------------------------------------------------
-- Set a fusion specific preference value
-- Example: setPreferenceData("sMrgSelected.sort", 1, true)
function setPreferenceData(pref, value, debugPrint)
-- Choose if you are saving the preference to the comp or to all of fusion
-- comp:SetData(pref, value)
fu:SetData(pref, value)
-- List the preference value
if (debugPrint == true) or (debugPrint == 1) then
if value == nil then
print("[Setting " .. tostring(pref) .. " Preference Data] " .. "nil")
else
print("[Setting " .. tostring(pref) .. " Preference Data] " .. tostring(value))
end
end
end
function Main()
local sort = getPreferenceData("sMrgSelected.sort", 1, 0)
local autoNameLayers = getPreferenceData("sMrgSelected.autoNameLayers", 1, 0)
local ui = fu.UIManager
local disp = bmd.UIDispatcher(ui)
local width,height = 300,70
win = disp:AddWindow({
ID = "sMerge",
TargetID = "sMerge",
WindowTitle = "sMerge Selected",
Geometry = {100, 100, width, height},
Spacing = 10,
ui:VGroup{
ID = "root",
ui:HGroup{
Weight = 0.01,
ui:Label{
ID = "SortLabel",
Text = "Sort Order",
},
ui:ComboBox{
ID = "SortMenu",
Text = "Sort Order",
},
},
ui:Button{
Weight = 0.01,
ID = "OKButton",
Text = "OK",
},
},
})
-- The window was closed
function win.On.sMerge.Close(ev)
disp:ExitLoop()
end
-- Add your GUI element based event functions here:
itm = win:GetItems()
-- Add the items to the ComboBox menu
itm.SortMenu:AddItem("Vertical Position")
itm.SortMenu:AddItem("Horizontal Position")
itm.SortMenu:AddItem("Node Name")
-- Restore the SortMenu preference
itm.SortMenu.CurrentIndex = sort
-- The app:AddConfig() command that will capture the "Control + W" or "Control + F4" hotkeys so they will close the window instead of closing the foreground composite.
app:AddConfig("sMerge", {
Target {
ID = "sMerge",
},
Hotkeys {
Target = "sMerge",
Defaults = true,
CONTROL_W = "Execute{cmd = [[app.UIManager:QueueEvent(obj, 'Close', {})]]}",
CONTROL_F4 = "Execute{cmd = [[app.UIManager:QueueEvent(obj, 'Close', {})]]}",
ESCAPE = "Execute{cmd = [[app.UIManager:QueueEvent(obj, 'Close', {})]]}"
},
})
function win.On.OKButton.Clicked(ev)
if itm.SortMenu.CurrentIndex == 0 then
sort = "Vertical Position"
elseif itm.SortMenu.CurrentIndex == 1 then
sort = "Horizontal Position"
elseif itm.SortMenu.CurrentIndex == 2 then
sort = "Node Name"
end
disp:ExitLoop()
end
win:Show()
disp:RunLoop()
win:Hide()
print("sMerge Selected")
print("[Sort by] ", sort)
setPreferenceData("sMrgSelected.sort", itm.SortMenu.CurrentIndex, VERBOSE)
-- Read the selection
local tools = comp:GetToolList(true)
local selectedTool = tool or comp.ActiveTool or tools and tools[1]
if selectedTool then
-- Check the selected node"s output type
toolOutput = selectedTool:FindMainOutput(1)
if toolOutput ~= nil then
toolType = toolOutput:GetAttrs().OUTS_DataType
-- Lock the comp flow area
comp:Lock()
-- Add the correct sMerge node
local mmrg
if toolType == "ShapeTree" then
if comp and comp.CurrentFrame and comp.CurrentFrame.FlowView then
if sort == "Vertical Position" then
table.sort(tools, function(a,b) return select(2, comp.CurrentFrame.FlowView:GetPos(a)) > select(2, comp.CurrentFrame.FlowView:GetPos(b)) end)
elseif sort == "Horizontal Position" then
table.sort(tools, function(a,b) return select(1, comp.CurrentFrame.FlowView:GetPos(a)) < select(1, comp.CurrentFrame.FlowView:GetPos(b)) end)
elseif sort == "Node Name" then
table.sort(tools, function(a,b) return a:GetAttrs().TOOLS_Name < b:GetAttrs().TOOLS_Name end)
end
else
print("[Error] This script can't find the Fusion flow view. Try using a single monitor layout if you want to sort the node input connections by \"Vertical Position\" or \"Horizontal Position\".")
end
sMrg = comp:AddTool("sMerge", -32768, -32768)
print("[Added Node] ", sMrg.Name)
-- Connect the inputs
for k,v in pairs(tools) do
-- Connect the Inputs
sMrg:ConnectInput("Input" .. (k), tools[k])
print(string.format("[%03d][Connection] %30s -> %s", k, tostring(tools[k].Name), tostring(sMrg.Name) .. ".Input" .. (k)))
end
end
-- Unlock the comp flow area
comp:Unlock()
end
end
end
Main()
print("[Done]\n\n")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment