Rename Multiple Layers With Index Number

Alrighty, I’ll keep it short and sweet with an example. Take, for instance, the following layers:
Screenshot 2024-02-03 065041

Say I want to rename all four of them a specific name, easy enough, highlight all four and set the name:
Screenshot 2024-02-03 065014

But what if I want to rename them and give them an index number as well? Any way to do this? Thank you!
Screenshot 2024-02-03 065125

1 Like

Hi @Ganglians. There is no option to do this, but if this action is very common for you, you can create your own script:
The simplest example:

  • Select the layers range
  • Then use this simple lua script:
local selectedLayes = app.range.layers
for i=1,#selectedLayes do
  selectedLayes[i].name = selectedLayes[i].name .. " " .. i
end
2 Likes

Below is my take on a layer rename dialog.

---@param layer Layer
---@param tally integer
---@param idLayerDict table<integer, integer>
---@return integer
local function layerHierarchy(layer, tally, idLayerDict)
    if layer.isGroup then
        local children <const> = layer.layers
        if children then
            local lenChildren <const> = #children
            local i = 0
            while i < lenChildren do
                i = i + 1
                tally = layerHierarchy(children[i], tally, idLayerDict)
            end
        end
    end

    idLayerDict[layer.id] = tally + 1
    return tally + 1
end

---@param sprite Sprite
---@return table<integer, integer>
local function spriteHierarchy(sprite)
    ---@type table<integer, integer>
    local idLayerDict <const> = {}
    local tally = 0
    local topLayers <const> = sprite.layers
    local lenTopLayers <const> = #topLayers
    local h = 0
    while h < lenTopLayers do
        h = h + 1
        tally = layerHierarchy(topLayers[h], tally, idLayerDict)
    end
    return idLayerDict
end

local dlg <const> = Dialog { title = "Layer Rename" }

dlg:entry {
    id = "nameEntry",
    label = "Name:",
    focus = true,
    text = "Layer"
}

dlg:newrow { always = false }

dlg:check {
    id = "reverse",
    label = "Order:",
    text = "&Reverse",
    selected = false
}

dlg:newrow { always = false }

dlg:button {
    id = "confirm",
    text = "&OK",
    focus = false,
    onclick = function()
        local sprite <const> = app.sprite
        if not sprite then return end

        local range <const> = app.range
        if range.sprite ~= sprite then return end

        local rangeLayers <const> = range.layers
        local lenRangeLayers <const> = #rangeLayers

        if lenRangeLayers <= 0 then return end

        local args <const> = dlg.data
        local nameEntry <const> = args.nameEntry --[[@as string]]
        local reverse <const> = args.reverse --[[@as boolean]]

        if lenRangeLayers <= 1 then
            app.transaction("Rename Layer", function()
                rangeLayers[1].name = nameEntry
            end)
            app.refresh()
            return
        end

        ---@type Layer[]
        local sortedLayers <const> = {}
        local j = 0
        while j < lenRangeLayers do
            j = j + 1
            sortedLayers[j] = rangeLayers[j]
        end

        local idLayerDict <const> = spriteHierarchy(sprite)
        table.sort(sortedLayers, function(a, b)
            return idLayerDict[a.id] < idLayerDict[b.id]
        end)

        local format <const> = "%s %d"
        local strfmt <const> = string.format
        local lenSortedLayers <const> = #sortedLayers

        app.transaction("Rename Layers", function()
            local i = 0
            while i < lenSortedLayers do
                i = i + 1
                local layer <const> = sortedLayers[i]
                local n <const> = reverse
                    and lenSortedLayers + 1 - i
                    or i
                layer.name = strfmt(format, nameEntry, n)
            end
        end)

        app.refresh()
    end
}

dlg:button {
    id = "cancel",
    text = "&CANCEL",
    focus = false,
    onclick = function()
        dlg:close()
    end
}

dlg:show {
    autoscrollbars = true,
    wait = false
}

Even in the simple case, where the layers in the range are selected sequentially (the Shift key is not held down when the user picks layers) and all the layers share the same parent, range layers need to be loaded into a separate table and sorted. In the simple case, stackIndex can be used as a sort criterion. This thread is where a method for counting layers recursively was previously discussed.

2 Likes

Sick, many thanks, I’ll check it out