// LabelColorPicker.jsx // Select layers in the timeline, click a color square to change their label color. // Install: drag into After Effects/Scripts/ScriptUI Panels/ then find it under Window menu. (function LabelColorPicker(thisObj) { var COLORS = [ { name: "None", label: 0, rgb: [0.31, 0.31, 0.31] }, { name: "Red", label: 1, rgb: [0.80, 0.23, 0.23] }, { name: "Yellow", label: 2, rgb: [0.86, 0.78, 0.19] }, { name: "Aqua", label: 3, rgb: [0.23, 0.78, 0.80] }, { name: "Pink", label: 4, rgb: [0.86, 0.39, 0.62] }, { name: "Lavender", label: 5, rgb: [0.55, 0.39, 0.82] }, { name: "Peach", label: 6, rgb: [0.86, 0.62, 0.39] }, { name: "Sea Foam", label: 7, rgb: [0.39, 0.78, 0.55] }, { name: "Blue", label: 8, rgb: [0.23, 0.39, 0.82] }, { name: "Green", label: 9, rgb: [0.31, 0.72, 0.31] }, { name: "Purple", label: 10, rgb: [0.66, 0.27, 0.70] }, { name: "Orange", label: 11, rgb: [0.86, 0.50, 0.19] }, { name: "Brown", label: 12, rgb: [0.58, 0.39, 0.23] }, { name: "Fuchsia", label: 13, rgb: [0.82, 0.23, 0.58] }, { name: "Cyan", label: 14, rgb: [0.19, 0.74, 0.82] }, { name: "Sandstone", label: 15, rgb: [0.74, 0.66, 0.47] }, { name: "Dark Teal", label: 16, rgb: [0.19, 0.50, 0.54] } ]; var SIZE = 36; // fixed — squares never scale var GAP = 4; var MARGINS = 10; var FOOTER_H = 22; function buildUI(container) { var isPanel = container instanceof Panel; var win = isPanel ? container : new Window("palette", "Label Colors", undefined, { resizeable: true }); // Stack orientation lets us control every element's position with bounds win.orientation = "stack"; win.margins = 0; win.spacing = 0; var allBtns = []; for (var i = 0; i < COLORS.length; i++) { var btn = win.add("button", [0, 0, SIZE, SIZE], ""); btn.helpTip = COLORS[i].name; btn.labelIndex = COLORS[i].label; allBtns.push(btn); (function(b, rgb) { b.onDraw = function() { var g = this.graphics; var w = this.size[0]; var h = this.size[1]; var bg = g.newBrush(g.BrushType.SOLID_COLOR, [rgb[0], rgb[1], rgb[2], 1]); var border = g.newPen(g.PenType.SOLID_COLOR, [0.1, 0.1, 0.1, 1], 1.5); g.rectPath(0, 0, w, h); g.fillPath(bg); g.strokePath(border); }; b.onClick = function() { var comp = app.project.activeItem; if (!comp || !(comp instanceof CompItem)) { alert("Open a composition first."); return; } var changed = 0; app.beginUndoGroup("Change Label Color"); for (var j = 1; j <= comp.numLayers; j++) { if (comp.layer(j).selected) { comp.layer(j).label = b.labelIndex; changed++; } } app.endUndoGroup(); if (changed === 0) alert("No layers selected in the timeline."); }; })(btn, COLORS[i].rgb); } // Footer — pinned to bottom, script font, dark grey var footer = win.add("statictext", [0, 0, 200, FOOTER_H], "Made by Design's Nock v1.0.0"); footer.justify = "center"; try { footer.graphics.font = ScriptUI.newFont("Segoe Script", "REGULAR", 11); } catch (e) { try { footer.graphics.font = ScriptUI.newFont("Georgia", "ITALIC", 11); } catch (e2) {} } footer.graphics.foregroundColor = footer.graphics.newPen( footer.graphics.PenType.SOLID_COLOR, [0.35, 0.35, 0.35, 1], 1 ); function relayout() { var winW = win.size[0]; var winH = win.size[1]; var availW = winW - 2 * MARGINS; // How many fixed-size squares fit per row? var cols = Math.max(1, Math.floor((availW + GAP) / (SIZE + GAP))); for (var k = 0; k < allBtns.length; k++) { var col = k % cols; var row = Math.floor(k / cols); var x = MARGINS + col * (SIZE + GAP); var y = MARGINS + row * (SIZE + GAP); allBtns[k].bounds = [x, y, x + SIZE, y + SIZE]; } // Footer always at bottom, full width var fW = Math.min(winW - 2 * MARGINS, 280); var fX = Math.floor((winW - fW) / 2); var fY = winH - MARGINS - FOOTER_H; footer.bounds = [fX, fY, fX + fW, fY + FOOTER_H]; } win.onResize = relayout; if (!isPanel) { // Compute a sensible default window size (6 columns) var initCols = 6; var initRows = Math.ceil(COLORS.length / initCols); var initW = 2 * MARGINS + initCols * SIZE + (initCols - 1) * GAP; var initH = 2 * MARGINS + initRows * SIZE + (initRows - 1) * GAP + GAP + FOOTER_H + MARGINS; win.size = [initW, initH]; relayout(); win.center(); win.show(); } else { win.layout.layout(true); relayout(); } return win; } buildUI(thisObj); })(this);