Create New Continuous Layer

Hello,

A few things if you want to keep working on this. Stack indices are relative to a layer’s parent, not the sprite.

stackIndices

A layer’s parent may either be another layer or the sprite.

A sprite’s layers array refers to its immediate children.

So maybe something like this if you want the new layer to appear above the old, but to share a parent.

local function countChildLayers(layer, sum)
    if layer.isGroup then
        local subLayers = layer.layers
        local localSum = 0
        for i = 1, #subLayers, 1 do
            local subLayer = subLayers[i]
            localSum = countChildLayers(subLayer, localSum)
        end
        return sum + 1 + localSum
    else
        return sum + 1
    end
end

local function countSpriteTotalLayers(sprite)
    local layers = sprite.layers
    local sum = 0
    for i = 1, #layers, 1 do
        local layer = layers[i]
        sum = countChildLayers(layer, sum)
    end
    return sum
end

app.transaction(function()
    local sprite = app.activeSprite
    local actLayer = app.activeLayer
	local index = actLayer.stackIndex
    local parent = actLayer.parent

    -- Create a new layer
    local newLayer = sprite:newLayer()
    newLayer.isContinuous = true 

    -- Creat a cel in the first frame of the layer, without this cels won't link
    sprite:newCel(newLayer, 1)

    -- Get all of the frame numbers into a table/array
    local frames = {}
    for frameNumber, _ in ipairs(sprite.frames) do
        table.insert(frames, frameNumber)
    end

    -- In order to select cels in range we need to specify both layers and frame - cels are their intersection
    app.range.frames = frames
    app.range.layers = {newLayer}

    app.command.LinkCels()

    app.range:clear()

    newLayer.parent = parent
	newLayer.stackIndex = index + 1
    newLayer.name = "Layer " .. countSpriteTotalLayers(sprite)
end)

Alternatively, you may want the new layer to appear at the top of the sprite stack no matter the active layer’s parent. Or you may not want a group layer to count towards the total sum of layers in a sprite.

A side complaint: The setter and getter for app.range.frames are weird. Looks like the setter takes frame numbers while the getter returns frame objects. I realize that at some point there was a change in how frames were handled elsewhere, so maybe this was overlooked? The documentation could be updated or the underlying API could be redesigned. If there can’t be reciprocity between a getter and a setter, then there should be separate methods and not a property.

Best,
Jeremy

2 Likes