Not sure it's possible to re-order the layers in another way. If anyone can figure out a different trick that'd be nice. Without the menu being alphabetically ordered the script isn't as useful as I hoped it would be.
Edit: Thanks for the help Wes, it works. This code below is the updated script.
Edit: Re-used frames now get their own color so you can distinguish them. (red = blank frame) (plain = regular drawing used once) (other color = re-used drawings)
Here it is:
Code: Select all
-- ************************************************************************************
-- Rename and sort sublayers of a FBF switchlayer to "Frame 1" etc. to match their first timeline appearance
-- ************************************************************************************
-- **************************************************
-- Provide Moho with the name of this script object
-- **************************************************
ScriptName = "LK_RenameFBFLayers"
-- **************************************************
-- General information about this script
-- **************************************************
LK_RenameFBFLayers = {}
function LK_RenameFBFLayers:Name()
	return "Rename FBF-frames"
end
function LK_RenameFBFLayers:Version()
	return "0"
end
function LK_RenameFBFLayers:Description()
	return "Rename and sort sublayers of a FBF switchlayer to 'Frame 1' etc. to match their time."
end
function LK_RenameFBFLayers:Creator()
	return "Lukas Krepel, Frame Order"
end
function LK_RenameFBFLayers:UILabel()
	return "Rename FBF-frames"
end
-- **************************************************
-- The guts of this script
-- **************************************************
function LK_RenameFBFLayers:IsEnabled(moho)
	if moho.layer:LayerType() ~= MOHO.LT_SWITCH then
		return false
	else
		local switchLayer = moho:LayerAsSwitch(moho.layer)
		if not switchLayer:IsFBFLayer() then
			return false
		end
	end
	return true
end
function LK_RenameFBFLayers:Run(moho)
	moho.document:PrepUndo(moho.layer)
	moho.document:SetDirty()
	LK_RenameFBFLayers:Rename(moho)
end
function LK_RenameFBFLayers:Rename(moho)
	local switchLayer = moho:LayerAsSwitch(moho.layer)
	local channel = switchLayer:SwitchValues() -- 10106 = CHANNEL_SWITCH
	local endKey = channel:Duration()
	local thisKey = 0
	local keyCount = channel:CountKeys()
	local keysFound = 0
	local frameNum = endKey
	local layers = {}
	for i = switchLayer:CountLayers()-1, 0, -1 do
		layer = switchLayer:Layer(i)
		table.insert(layers, layer)
	end
	for i = 1, #layers do
		local layer = layers[i]
		layer:SetName("tempname "..i)
	end
	local frameLayers = {}
	local alreadyColored = {}
	local reuseColors = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }
		local col = 1
	while keysFound < keyCount do
		keysFound = 1 + keysFound
		thisKey = channel:GetClosestKeyID(frameNum)
		keyFrameNum = channel:GetKeyWhen(thisKey)
		local leadingZeros = string.format("%05d", keyFrameNum)
		local newName = "Frame_"..leadingZeros
		local keyValue = switchLayer:GetValue(keyFrameNum)
		frameNum = keyFrameNum - 1
		
		for i = 1, #layers do
			local layer = layers[i]
			local layerName = layer:Name()
			if layerName == keyValue then
				
				if table.contains(frameLayers, layer) then
					if not table.contains(alreadyColored, layer) then
						local color = reuseColors[col]
						col = col + 1
						layer:SetLabelColor(color) -- * From table For re-used frames.
						table.insert(alreadyColored, layer)
						layer:SetName(newName.." *")
					end
				else
					layer:SetName(newName)
					layer:SetLabelColor(0) -- * 0 = Plain -- For regular frames.
				end
                local mesh = moho:LayerAsVector(layer):Mesh()
                if mesh:CountPoints() == 0 then
					layer:SetLabelColor(1) -- * 2 = orange -- For empty frames.
					if table.contains(frameLayers, layer) then
						--layer:SetLabelColor(1) -- * 1 = red -- For re-used empty frame.
					end
				end
				table.insert(frameLayers, layer)
			end
		end
	end
	local unusedCount = 0
	local blankReusedCount = 1
	for i = 1, #layers do
		local layer = layers[i]
		if layer:LabelColor() == 1 then
			if blankReusedCount == 1 then
				layer:SetName("Blank")
			else
				layer:SetName("Blank "..blankReusedCount)
			end
			blankReusedCount = blankReusedCount + 1
		end
		if not table.contains(frameLayers, layer) then
			unusedCount = unusedCount + 1
			layer:SetName("Unused_"..unusedCount)
			layer:SetLabelColor(1) -- * 1 = red
		end
	end
	self:SortByName(moho)
end
-- **************************************************
-- Sort layers by name
-- **************************************************
function LK_RenameFBFLayers:SortByName(moho)
	-- * Create table
	local thisLayer = moho:LayerAsGroup(moho.layer)
	thisLayer:EnableLayerOrdering(false)
	local order, layer, layerName = {}
	for i = thisLayer:CountLayers()-1, 0, -1 do
		layer = thisLayer:Layer(i)
		layerName = layer:Name()
		table.insert(order, {layer, layerName})
	end
	-- * Sort table alphabetically:
	table.sort(order,
		function(a,b)
			return (a[2]<b[2])
		end)
	-- * Sort layer order:
	if #order > 1 then
		for i = 1, #order-1 do
			local moveLayer = order[i+1][1]
			local behindLayer = order[i][1]
			moho:PlaceLayerBehindAnother(moveLayer, behindLayer)
		end
	end
	-- *
	moho.layer:UpdateCurFrame()
	moho.view:DrawMe()
end
-- **************************************************
-- Check whether a table contains an element
-- **************************************************
function table.contains(table, element)
	if table ~= nil then
		for _, value in pairs(table) do
			if value == element then
	    		return true
	    	end
	  	end
	end
  	return false
endCode: Select all
moho.document:PrepUndo(moho.layer)
moho.document:SetDirty()
local switchLayer = moho:LayerAsSwitch(moho.layer)
local currentLayerName = switchLayer:GetValue(moho.frame)
local layers = {}
for i = switchLayer:CountLayers()-1, 0, -1 do
	layer = switchLayer:Layer(i)
	table.insert(layers, layer)
end
local encounter = false
for i = 1, #layers do
	local layer = layers[i]
	local layerName = layer:Name()
	--print (layerName.." == "..currentLayerName)
	if layerName == currentLayerName then
		encounter = true
		moho:SetSelLayer(layer, false, false)
		break
	end
end
if not encounter then
	print ("error... "..currentLayerName)
	return
end
moho:CreateNewLayer(LT_VECTOR, false)
local channel = switchLayer:SwitchValues() -- 10106 = CHANNEL_SWITCH
channel.value:Set(moho.layer:Name())
channel:StoreValue()
moho:SetSelLayer(switchLayer, false, false)
LK_RenameFBFLayers:Rename(moho)
moho:UpdateUI()