Image
-- **************************************************
-- Provide Moho with the name of this script object
-- **************************************************
ScriptName = "LK_EmbedScript"

-- **************************************************
-- General information about this script
-- **************************************************
LK_EmbedScript = {}

function LK_EmbedScript:ColorizeIcon()
	return true
end

function LK_EmbedScript:Name()
	return "Embed script"
end

function LK_EmbedScript:Version()
	return "0.1"
end

function LK_EmbedScript:Description()
	return "Embed, reload and remove layerscripts. Only works with scripts that are located in the <Embedded Scripts> folder (which should contain <LK_Dummy.lua> in order for reloading to work) inside the <Shared Resources> folder."
end

function LK_EmbedScript:Creator()
	return "Lukas Krepel Frame Order"
end

function LK_EmbedScript:UILabel()
	return "Embed layerscripts"
end

function LK_EmbedScript:OnMouseDown(moho, mouseEvent)

end

-- **************************************************
-- Is Relevant / Is Enabled
-- **************************************************
function LK_EmbedScript:IsEnabled(moho)
	return true
end

function LK_EmbedScript:IsRelevant(moho)
	if MohoMode ~= nil then
		return MohoMode.rigging
	end
	return true
end

-- **************************************************
-- Tool options - create and respond to tool's UI
-- **************************************************
LK_EmbedScript.CLEAR_EMBED					= MOHO.MSG_BASE + 0
LK_EmbedScript.RELOAD_EMBED					= MOHO.MSG_BASE + 1
LK_EmbedScript.FIND_EMBED					= MOHO.MSG_BASE + 2
LK_EmbedScript.EDIT_SCRIPT					= MOHO.MSG_BASE + 3
LK_EmbedScript.EXAMPLE_FILE 				= MOHO.MSG_BASE + 4
LK_EmbedScript.REVEAL_DIRECTORY				= MOHO.MSG_BASE + 5
LK_EmbedScript.DO_NOTHING 					= MOHO.MSG_BASE + 6
LK_EmbedScript.OPTION						= MOHO.MSG_BASE + 100

function LK_EmbedScript:DoLayout(moho, layout)
	FO_Utilities.tinyUI = false
	local userpath = string.gsub(moho:UserAppDir(), '\\', '/')
	self.layerscriptsfolder = userpath .. "/Shared Resources/Layerscripts/"
	-- * Text:
	layout:AddChild(LM.GUI.StaticText("Current layer's embeddedscript:"))
	layout:PushH(LM.GUI.ALIGN_CENTER, 0)
	-- * Filename field:
	self.currentEmbed = LM.GUI.TextControl(250, "No script embedded.", self.DO_NOTHING, LM.GUI.FIELD_TEXT, nil)
	layout:AddChild(self.currentEmbed)
	-- * Reload current script button:
	self.RELOAD_EMBED_Button = LM.GUI.ImageButton("ScriptResources/FO_icons/refresh", "Reload embedded layerscript", false, self.RELOAD_EMBED, true)
	layout:AddChild(self.RELOAD_EMBED_Button)
	-- * Clear embedded script button:
	self.CLEAR_EMBED_Button = LM.GUI.ImageButton("ScriptResources/FO_icons/trashcan", "Clear embedded layerscript", false, self.CLEAR_EMBED, true)
	layout:AddChild(self.CLEAR_EMBED_Button)
	-- * Sample file button:
	self.EXAMPLE_FILE_Button = LM.GUI.ImageButton("ScriptResources/FO_icons/questionmark", "Open example Moho file", false, self.EXAMPLE_FILE, true)
	layout:AddChild(self.EXAMPLE_FILE_Button)
	layout:Pop()
	-- * Divider:
	layout:AddChild(LM.GUI.Divider(true), LM.GUI.ALIGN_FILL, 0)
	-- * Dropdown menu:
	self.menu = LM.GUI.Menu("Embed layerscript")
    self.popup = LM.GUI.PopupMenu(120, false)
    self.popup:SetMenu(self.menu)
    layout:AddChild(self.popup)
	self.layerscripts = FO_Utilities:ListFiles(self.layerscriptsfolder, moho)
	local i
	for i = 1, #self.layerscripts do
		local number = self.OPTION + i
		local layerscriptFilename = self.layerscripts[i]
		self.menu:AddItem(layerscriptFilename, 0, number)
		-- *** LM_Menu:AddItem(label, shortcut, msg) *** ?
	end
	self.menu:AddItem("______", 0, 0) -- * ?
	self.menu:AddItem("Reveal Directory", 0, self.REVEAL_DIRECTORY)
	-- * Divider:
	layout:AddChild(LM.GUI.Divider(true), LM.GUI.ALIGN_FILL, 0)
	layout:PushH(LM.GUI.ALIGN_CENTER, 2)
	-- * Find al embedded scripts button:
	self.FindEmbedButton = LM.GUI.ImageButton("ScriptResources/FO_icons/txt_embed_find", "Find all embedded layerscripts in document", true, self.FIND_EMBED, true)
	layout:AddChild(self.FindEmbedButton)
	-- * Edit script button:
	self.EditScriptButton = LM.GUI.ImageButton("ScriptResources/FO_icons/edit_script", "Edit embedded layerscript in Sublime Text", false, self.EDIT_SCRIPT, true)
	layout:AddChild(self.EditScriptButton)
	layout:Pop()
	-- * Divider:
	layout:AddChild(LM.GUI.Divider(true), LM.GUI.ALIGN_FILL, 0)
	-- * Doc overview:
	self.docOverviewText = LM.GUI.DynamicText("(Document contains X layers with an embedded script and X unique layerscripts.)", 500)
	layout:AddChild(self.docOverviewText)
end

-- **************************************************
-- Update Toolbar Widgets
-- **************************************************
function LK_EmbedScript:UpdateWidgets(moho)
	local layer = moho.document:GetSelectedLayer(0)
	local embeddedscript = layer:LayerScript()
	embeddedscript = string.gsub(tostring(layer:LayerScript()), '\\', '/')
	if embeddedscript ~= "" then
		local lastslashpos = (embeddedscript:reverse()):find("%/") -- find last slash
		embeddedscript = (embeddedscript:sub(-lastslashpos+1)) -- filename only
		self.CLEAR_EMBED_Button:Enable(true)
		self.RELOAD_EMBED_Button:Enable(true)
		self.currentEmbed:Enable(true)
		self.EditScriptButton:Enable(true)
		-- * Example file button:
		local userpath = string.gsub(moho:UserAppDir(), '\\', '/')
		local examplefile = string.gsub(embeddedscript, "lua", "moho")
		local examplefilepath = userpath .. "/Library/Layerscript Examples/"..examplefile
		local examplefileExists = FO_Utilities:FileExists(moho, examplefilepath)
		self.EXAMPLE_FILE_Button:Enable(examplefileExists)
		if examplefileExists then
			self.EXAMPLE_FILE_Button:SetToolTip("Open example file: \""..examplefilepath.."\"")
		else
			self.EXAMPLE_FILE_Button:SetToolTip("Example file does not exist at: \""..examplefilepath.."\"")
		end
	else
		embeddedscript = "No script embedded."
		self.CLEAR_EMBED_Button:Enable(false)
		self.RELOAD_EMBED_Button:Enable(false)
		self.currentEmbed:Enable(false)
		self.EditScriptButton:Enable(false)
		self.EXAMPLE_FILE_Button:Enable(false)
	end
	self.currentEmbed:SetValue(embeddedscript)
	if (moho:LayersWindowGetSearchContext() == 8 and moho:LayersWindowGetSearchContextValue() == FO_Utilities.embedTag) then
		self.FindEmbedButton:SetValue(true)
	else
		self.FindEmbedButton:SetValue(false)
	end
	--
	local layers = FO_Utilities:AllLayers(moho)
	local layerCount = 0
	uniqueScripts = {}
	for i = 1, #layers do
		local layer = layers[i]
		local layerscript = tostring(layer:LayerScript())
		if layerscript ~= "" then
			layerCount = layerCount + 1
			if not table.contains(uniqueScripts, layerscript) then
				table.insert(uniqueScripts, layerscript)
			end
		end
	end
	if layerCount == 1 then
		layerCount = "1 layer"
	else
		layerCount = layerCount.." layers"
	end
	self.docOverviewText:SetValue("(Document contains "..layerCount.." with an embedded script and a total of "..#uniqueScripts.." unique layerscripts.)")
	-- * Checkmark:
	self.layerscripts = FO_Utilities:ListFiles(self.layerscriptsfolder, moho)
	local i
	for i = 1, #self.layerscripts do
		local file = self.layerscripts[i]
		local check = self.layerscripts[i] == embeddedscript
		self.menu:SetChecked(self.OPTION + i, check)
	end
end

-- **************************************************
-- Handle Messages
-- **************************************************
function LK_EmbedScript:HandleMessage(moho, view, msg)
	local scriptpath
	-- * Check which message:
	if msg == self.CLEAR_EMBED then
		moho.document:PrepMultiUndo()
		moho.document:SetDirty()
		local selCount = moho.document:CountSelectedLayers()
		for i = 0, selCount - 1 do
			local layer = moho.document:GetSelectedLayer(i)
			layer:SetLayerScript(nil)
			layer:SetLabelColor(0)
			FO_Utilities:RemoveTag(FO_Utilities.embedTag, layer)
		end
	elseif msg == self.RELOAD_EMBED then
		local layer = moho.document:GetSelectedLayer(0)
		local reloadscript = tostring(layer:LayerScript())
		local tempscript = (self.layerscriptsfolder .. "LK_Dummy.lua")
		local layers = FO_Utilities:AllLayers(moho)
		local i
		local count = 0
		for i = 1, #layers do
			layer = layers[i]
			local embeddedscript = tostring(layer:LayerScript()) -- * Full path
			if embeddedscript == reloadscript then
				-- * First remove script of all layers by embedding a temporary layerscript:
				layer:SetLayerScript(tempscript)
				-- * Set chosen script:
				layer:SetLayerScript(reloadscript)
				-- * Counter:
				count = count + 1
			end
		end
		if count == 1 then
			count = "1 layer"
		else
			count = count.." layers"
		end
		-- * Printing message instead of alerting trough a popup, for debug purposes:
		print "-----------"
		print (reloadscript .. " has been reloaded for "..count)
		print "-----------"
	elseif msg == self.FIND_EMBED then
		-- * Find layerscripts:
		local layers = FO_Utilities:AllLayers(moho)
		for i = 1, #layers do
			local layer = layers[i]
			if tostring(layer:LayerScript()) ~= "" then
				FO_Utilities:AddTag(FO_Utilities.embedTag, layer)
			else
				FO_Utilities:RemoveTag(FO_Utilities.embedTag, layer)
			end
		end
		FO_Utilities:FilterTag(FO_Utilities.embedTag, false, moho)
	elseif msg == self.EXAMPLE_FILE then
		local embeddedscript = moho.layer:LayerScript()
		embeddedscript = string.gsub(tostring(embeddedscript), '\\', '/')
		local lastslashpos = (embeddedscript:reverse()):find("%/") -- find last slash
		embeddedscript = (embeddedscript:sub(-lastslashpos+1)) -- filename only
		local userpath = string.gsub(moho:UserAppDir(), '\\', '/')
		local examplefile = string.gsub(embeddedscript, "lua", "moho")
		local examplefilepath = userpath .. "/Library/Layerscript Examples/"..examplefile
		if FO_Utilities:FileExists(moho, examplefilepath) then
			print ("-- **********************************************************************")
			print ("-- *** Lua function:")
			print ("-- *** \"moho:FileOpen("..examplefilepath..")\"")
			print ("-- *** crashes Moho and I don't know why. Please open file manually.")
			print ("-- **********************************************************************")
			-- moho:FileOpen(examplefilepath) -- * CRASHES!!!
		end
	elseif msg == self.REVEAL_DIRECTORY then
		FO_Utilities:RevealDirectory(self.layerscriptsfolder)
	elseif msg > self.OPTION then
		option = (msg - self.OPTION)
		script = (tostring(self.layerscripts[option]))
		moho.document:PrepMultiUndo()
		moho.document:SetDirty()
		scriptpath = (self.layerscriptsfolder .. script)
		local selCount = moho.document:CountSelectedLayers()
		for i = 0, selCount - 1 do
			local layer = moho.document:GetSelectedLayer(i)
			layer:SetLayerScript(scriptpath)
			FO_Utilities:AddTag(FO_Utilities.embedTag, layer)
			layer:SetLabelColor(7)
		end
	elseif msg == self.EDIT_SCRIPT then
		local layer = moho.document:GetSelectedLayer(0)
		local embeddedscript = layer:LayerScript()
		FO_Utilities:EditTextFile(embeddedscript, moho)
	end
	-- * Update UI:
	FO_Utilities:ReloadTools(moho)
	moho:UpdateUI()
end

Icon
Embed Script
Listed

Author: Lukas View Script
Script type: Tool

Uploaded: May 25 2023, 04:26

Last modified: Sep 05 2023, 12:54

Script Version: 0.1

Tool to embed/reload/remove/edit layerscripts
The tool that allows you to quickly embed, reload(!) and edit embedded layerscripts that are saved in the custom content folder. It will try to use Sublime Text as an editor for the lua files, but you could adjust that to any other editor.

You need a folder called "Layerscripts" in your "Shared Resources" folder in the Custom Content Folder. Put all your layerscripts there:

~/Custom Content Folder/Moho Pro/Shared Resources/Layerscripts/LK_Dummy.lua

The layerscripts folder should contain LK_Dummy.lua. It is necessary for reloading scripts.

Image

Forum post
This script, and all other scripts on this site are distributed as free software under the GNU General Public License 3.0 or later.
Downloads count: 821