-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
gridTemplate.lua
1086 lines (940 loc) · 34 KB
/
gridTemplate.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
local labelTypes <const> = {
"LEFT",
"RIGHT",
"TOP",
"BOTTOM"
}
local patternTypes <const> = {
"DIAMOND",
"RECTANGLE",
"RHOMBUS"
}
local defaults <const> = {
-- Should sliders be replaced with number inputs to give user greater
-- flexibility on scale?
cols = 5,
rows = 5,
margin = 3,
padding = 2,
border = 0,
cellWidth = 32,
cellHeight = 32,
opacity = 255,
patternType = "RECTANGLE",
wChecker = 16,
hChecker = 16,
szDiam = 16,
xChecker = 0,
yChecker = 0,
headerHeight = 0,
labelType = "BOTTOM",
labelSize = 0,
genSlices = false,
frames = 1,
fps = 12,
lockGrid = true,
closeGroups = true,
layerColorBlue01 = 43,
layerColorBlue02 = 85,
layerColorBlue03 = 128,
layerColorAlpha = 85
}
---@param c Color
---@return Color
local function colorCopy(c)
return Color { r = c.red, g = c.green, b = c.blue, a = c.alpha }
end
local dlg <const> = Dialog { title = "Grid Template" }
dlg:slider {
id = "cols",
label = "Cells:",
min = 1,
max = 32,
value = defaults.cols
}
dlg:slider {
id = "rows",
min = 1,
max = 32,
value = defaults.rows
}
dlg:newrow { always = false }
dlg:number {
id = "cellWidth",
label = "Size:",
text = string.format("%d", defaults.cellWidth),
decimals = 0
}
dlg:number {
id = "cellHeight",
text = string.format("%d", defaults.cellHeight),
decimals = 0
}
dlg:newrow { always = false }
dlg:slider {
id = "margin",
label = "Margin:",
min = 0,
max = 32,
value = defaults.margin
}
dlg:newrow { always = false }
dlg:slider {
id = "padding",
label = "Padding:",
min = 0,
max = 32,
value = defaults.padding
}
dlg:newrow { always = false }
dlg:slider {
id = "border",
label = "Border:",
min = 0,
max = 32,
value = defaults.border,
onchange = function()
local args <const> = dlg.data
local sizeBorder <const> = args.border --[[@as integer]]
local validSize <const> = sizeBorder > 0
dlg:modify { id = "borderClr", visible = validSize }
end
}
dlg:newrow { always = false }
dlg:color {
id = "borderClr",
color = Color { r = 119, g = 119, b = 119 },
visible = defaults.border > 0
}
dlg:newrow { always = false }
dlg:combobox {
id = "patternType",
label = "Pattern:",
option = defaults.patternType,
options = patternTypes,
onchange = function()
local args <const> = dlg.data
local patternType <const> = args.patternType --[[@as string]]
local isDiam <const> = patternType == "DIAMOND"
or patternType == "RHOMBUS"
local isRect <const> = patternType == "RECTANGLE"
dlg:modify { id = "szDiam", visible = isDiam }
dlg:modify { id = "wChecker", visible = isRect }
dlg:modify { id = "hChecker", visible = isRect }
local validSize = false
if isDiam then
local szDiam <const> = args.szDiam --[[@as integer]]
validSize = szDiam > 1
else
local wChecker <const> = args.wChecker --[[@as integer]]
local hChecker <const> = args.hChecker --[[@as integer]]
validSize = wChecker > 0 and hChecker > 0
end
dlg:modify { id = "bChecker", visible = validSize }
dlg:modify { id = "xChecker", visible = validSize }
dlg:modify { id = "yChecker", visible = validSize }
end
}
dlg:newrow { always = false }
dlg:slider {
id = "szDiam",
label = "Diamond:",
min = 4,
max = 64,
value = defaults.szDiam,
visible = defaults.patternType == "DIAMOND"
or defaults.patternType == "RHOMBUS",
onchange = function()
local args <const> = dlg.data
local szDiam <const> = args.szDiam --[[@as integer]]
local validSize <const> = szDiam > 1
dlg:modify { id = "bChecker", visible = validSize }
dlg:modify { id = "xChecker", visible = validSize }
dlg:modify { id = "yChecker", visible = validSize }
end
}
dlg:slider {
id = "wChecker",
label = "Checker:",
min = 0,
max = 64,
value = defaults.wChecker,
visible = defaults.patternType == "RECTANGLE",
onchange = function()
local args <const> = dlg.data
local wChecker <const> = args.wChecker --[[@as integer]]
local hChecker <const> = args.hChecker --[[@as integer]]
local validSize <const> = wChecker > 0 and hChecker > 0
dlg:modify { id = "bChecker", visible = validSize }
dlg:modify { id = "xChecker", visible = validSize }
dlg:modify { id = "yChecker", visible = validSize }
end
}
dlg:slider {
id = "hChecker",
min = 0,
max = 64,
value = defaults.hChecker,
visible = defaults.patternType == "RECTANGLE",
onchange = function()
local args <const> = dlg.data
local wChecker <const> = args.wChecker --[[@as integer]]
local hChecker <const> = args.hChecker --[[@as integer]]
local validSize <const> = wChecker > 0 and hChecker > 0
dlg:modify { id = "bChecker", visible = validSize }
dlg:modify { id = "xChecker", visible = validSize }
dlg:modify { id = "yChecker", visible = validSize }
end
}
dlg:newrow { always = false }
dlg:slider {
id = "xChecker",
label = "Offset:",
min = -32,
max = 31,
value = defaults.xChecker,
visible = defaults.wChecker > 0
and defaults.hChecker > 0
}
dlg:slider {
id = "yChecker",
min = -32,
max = 31,
value = defaults.yChecker,
visible = defaults.wChecker > 0
and defaults.hChecker > 0
}
dlg:newrow { always = false }
dlg:color {
id = "aChecker",
label = "Color:",
color = Color { r = 71, g = 71, b = 71 }
}
dlg:color {
id = "bChecker",
color = Color { r = 96, g = 96, b = 96 },
visible = defaults.wChecker > 0
and defaults.hChecker > 0
}
dlg:newrow { always = false }
dlg:number {
id = "headerHeight",
label = "Header:",
text = string.format("%d", defaults.headerHeight),
decimals = 0,
onchange = function()
local args <const> = dlg.data
local headerHeight <const> = args.headerHeight --[[@as number]]
local isValid <const> = headerHeight > 0
dlg:modify { id = "headerClr", visible = isValid }
end
}
dlg:newrow { always = false }
dlg:color {
id = "headerClr",
color = Color { r = 48, g = 48, b = 48 },
visible = defaults.headerHeight > 0
}
dlg:newrow { always = false }
dlg:combobox {
id = "labelType",
label = "Label:",
option = defaults.labelType,
options = labelTypes
}
dlg:newrow { always = false }
dlg:number {
id = "labelSize",
text = string.format("%d", defaults.labelSize),
decimals = 0,
onchange = function()
local args <const> = dlg.data
local labelSize <const> = args.labelSize --[[@as number]]
local isValid <const> = labelSize > 0
dlg:modify { id = "labelClr", visible = isValid }
end
}
dlg:newrow { always = false }
dlg:color {
id = "labelClr",
color = Color { r = 48, g = 48, b = 48 },
visible = defaults.labelSize > 0
}
dlg:newrow { always = false }
dlg:color {
id = "bkgClr",
label = "Background:",
color = Color { r = 27, g = 27, b = 27 }
}
dlg:newrow { always = false }
dlg:slider {
id = "opacity",
label = "Opacity:",
min = 1,
max = 255,
value = defaults.opacity,
visible = false
}
dlg:newrow { always = false }
dlg:slider {
id = "frames",
label = "Frames:",
min = 1,
max = 96,
value = defaults.frames,
visible = false
}
dlg:newrow { always = false }
dlg:slider {
id = "fps",
label = "FPS:",
min = 1,
max = 50,
value = defaults.fps,
visible = false
}
dlg:newrow { always = false }
dlg:check {
id = "genSlices",
label = "Include:",
text = "&Slices",
selected = defaults.genSlices,
visible = true
}
dlg:newrow { always = false }
dlg:button {
id = "confirm",
text = "&OK",
focus = true,
onclick = function()
local args <const> = dlg.data
local cellWidth <const> = args.cellWidth
or defaults.cellWidth --[[@as number]]
local cellHeight <const> = args.cellHeight
or defaults.cellHeight --[[@as number]]
local cols <const> = args.cols
or defaults.cols --[[@as integer]]
local rows <const> = args.rows
or defaults.rows --[[@as integer]]
local margin <const> = args.margin
or defaults.margin --[[@as integer]]
local padding <const> = args.padding
or defaults.padding --[[@as integer]]
local border = args.border
or defaults.border --[[@as integer]]
local patternType <const> = args.patternType
or defaults.patternType --[[@as string]]
local wCheck <const> = args.wChecker
or defaults.wChecker --[[@as integer]]
local hCheck <const> = args.hChecker
or defaults.hChecker --[[@as integer]]
local szDiam <const> = args.szDiam
or defaults.szDiam --[[@as integer]]
local xCheck <const> = args.xChecker
or defaults.xChecker --[[@as integer]]
local yCheck <const> = args.yChecker
or defaults.yChecker --[[@as integer]]
local headerHeight <const> = args.headerHeight
or defaults.headerHeight --[[@as number]]
local labelType <const> = args.labelType
or defaults.labelType --[[@as string]]
local labelSize <const> = args.labelSize
or defaults.labelSize --[[@as number]]
local opacity <const> = args.opacity
or defaults.opacity --[[@as integer]]
local frameReqs <const> = args.frames
or defaults.frames --[[@as integer]]
local fps <const> = args.fps
or defaults.fps --[[@as integer]]
local genSlices = args.genSlices --[[@as boolean]]
local aCheckerRef <const> = args.aChecker --[[@as Color]]
local bCheckerRef <const> = args.bChecker --[[@as Color]]
local bkgClrRef <const> = args.bkgClr --[[@as Color]]
local borderClrRef <const> = args.borderClr --[[@as Color]]
local headerClrRef <const> = args.headerClr --[[@as Color]]
local labelClrRef <const> = args.labelClr --[[@as Color]]
local aChecker <const> = colorCopy(aCheckerRef)
local bChecker <const> = colorCopy(bCheckerRef)
local bkgClr <const> = colorCopy(bkgClrRef)
local borderClr <const> = colorCopy(borderClrRef)
local headerClr <const> = colorCopy(headerClrRef)
local labelClr <const> = colorCopy(labelClrRef)
aChecker.alpha = 255
bChecker.alpha = 255
bkgClr.alpha = 255
borderClr.alpha = 255
headerClr.alpha = 255
labelClr.alpha = 255
local editGrid <const> = not defaults.lockGrid
local closeGroups <const> = defaults.closeGroups
local layerColorBlue01 <const> = defaults.layerColorBlue01
local layerColorBlue02 <const> = defaults.layerColorBlue02
local layerColorBlue03 <const> = defaults.layerColorBlue03
local layerColorAlpha <const> = defaults.layerColorAlpha
local cwVrf <const> = math.max(2,
math.floor(0.5 + math.abs(cellWidth)))
local chVrf <const> = math.max(2,
math.floor(0.5 + math.abs(cellHeight)))
local headVrf <const> = math.max(0,
math.floor(0.5 + math.abs(headerHeight)))
local labelVrf <const> = math.max(0,
math.floor(0.5 + math.abs(labelSize)))
local margin2 <const> = margin + margin
local border2 <const> = border + border
local colsn1 <const> = cols - 1
local rowsn1 <const> = rows - 1
local flatLen <const> = rows * cols
local useHeader <const> = headVrf > 0
local useBkg <const> = bkgClrRef.alpha > 0
local useBdr <const> = borderClrRef.alpha > 0 and border > 0
local useLabel <const> = labelVrf > 0
local oneFrame <const> = frameReqs <= 1
if not useBdr then border = 0 end
local xGridOffset <const> = margin
local yGridOffset = margin
if useHeader then
yGridOffset = margin
+ padding + headVrf
end
local rowToGreen = 0.0
local colToRed = 0.0
if rowsn1 ~= 0 then rowToGreen = 255.0 / rowsn1 end
if colsn1 ~= 0 then colToRed = 255.0 / colsn1 end
local aHex <const> = aChecker.rgbaPixel
local bHex <const> = bChecker.rgbaPixel
local bkgHex <const> = bkgClr.rgbaPixel
-- Update whenever new elements are added to a cell.
local wCellTotal = cwVrf + border2
local hCellTotal = chVrf + border2
if useLabel then
if labelType == "LEFT"
or labelType == "RIGHT" then
wCellTotal = wCellTotal + labelVrf
elseif labelType == "TOP"
or labelType == "BOTTOM" then
hCellTotal = hCellTotal + labelVrf
end
end
local spriteWidth <const> = margin2
+ wCellTotal * cols
+ padding * colsn1
local spriteHeight = margin2
+ hCellTotal * rows
+ padding * rowsn1
if useHeader then
spriteHeight = spriteHeight
+ headVrf
+ padding
end
-- As a precaution against crashes, do not allow slices UI interface
-- to be active.
local appTool <const> = app.tool
if appTool then
local toolName <const> = appTool.id
if toolName == "slice" then
app.tool = "hand"
end
end
local spriteSpec <const> = ImageSpec {
width = spriteWidth,
height = spriteHeight,
colorMode = ColorMode.RGB,
transparentColor = 0
}
local activeSprite <const> = Sprite(spriteSpec)
activeSprite.filename = "Grid"
app.transaction("Set Grid Bounds", function()
local wGrid <const> = cols > 1
and wCellTotal + padding
or wCellTotal
local hGrid <const> = rows > 1
and hCellTotal + padding
or hCellTotal
activeSprite.gridBounds = Rectangle(
xGridOffset, yGridOffset,
wGrid, hGrid)
end)
-- Ase a precaution against any crashes, do not use defaultPalette.
app.transaction("Set Palette", function()
local palette <const> = activeSprite.palettes[1]
palette:resize(7)
palette:setColor(0, Color { r = 0, g = 0, b = 0, a = 0 })
palette:setColor(1, bkgClr)
palette:setColor(2, aChecker)
palette:setColor(3, bChecker)
palette:setColor(4, borderClr)
palette:setColor(5, headerClr)
palette:setColor(6, labelClr)
end)
local activeLayer <const> = activeSprite.layers[1]
local checkSpec <const> = ImageSpec(spriteSpec)
checkSpec.width = cwVrf
checkSpec.height = chVrf
local checkImage <const> = Image(checkSpec)
local validColorDiff <const> = aHex ~= bHex
local validChecker <const> = validColorDiff
and patternType == "RECTANGLE"
and wCheck >= 1
and hCheck >= 1
local validDiamond <const> = validColorDiff
and (patternType == "DIAMOND"
or patternType == "RHOMBUS")
and szDiam >= 4
-- TODO: Replace with string bytes...
local pxItr <const> = checkImage:pixels()
if validDiamond then
local yScale = 1
if patternType == "RHOMBUS" then yScale = 2 end
local halfSize <const> = szDiam * 0.5
local abs <const> = math.abs
for pixel in pxItr do
local xPx <const> = pixel.x - xCheck
local yPx <const> = yScale * (pixel.y - yCheck)
local xLocal <const> = xPx % szDiam
local yLocal <const> = yPx % szDiam
local manhDist <const> = abs(xLocal - halfSize)
+ abs(yLocal - halfSize)
local hex <const> = manhDist <= halfSize and aHex or bHex
pixel(hex)
end
elseif validChecker then
for pixel in pxItr do
local xPx <const> = pixel.x - xCheck
local yPx <const> = pixel.y - yCheck
local hex = bHex
if ((xPx // wCheck + yPx // hCheck) % 2) ~= 1 then
hex = aHex
end
pixel(hex)
end
else
checkImage:clear(aHex)
end
local labelImage = nil
local xLabelDisplace = 0
local yLabelDisplace = 0
local xLabelLoc = 0
local yLabelLoc = 0
if useLabel then
local wLabel = 0
local hLabel = 0
if labelType == "LEFT" then
xLabelDisplace = labelVrf
wLabel = labelVrf
hLabel = hCellTotal
elseif labelType == "RIGHT" then
xLabelLoc = cwVrf + border2
wLabel = labelVrf
hLabel = hCellTotal
elseif labelType == "TOP" then
yLabelDisplace = labelVrf
wLabel = wCellTotal
hLabel = labelVrf
elseif labelType == "BOTTOM" then
yLabelLoc = chVrf + border2
wLabel = wCellTotal
hLabel = labelVrf
end
local labelSpec <const> = ImageSpec(spriteSpec)
labelSpec.width = wLabel
labelSpec.height = hLabel
labelImage = Image(labelSpec)
if labelClr.alpha > 0 then
local labelHex <const> = labelClr.rgbaPixel
labelImage:clear(labelHex)
end
end
local bdrImage = nil
if useBdr then
local bdrSpec <const> = ImageSpec(spriteSpec)
local wBordered <const> = cwVrf + border2
local hBordered <const> = chVrf + border2
bdrSpec.width = wBordered
bdrSpec.height = hBordered
bdrImage = Image(bdrSpec)
local highStr <const> = string.pack("B B B B",
borderClr.red,
borderClr.green,
borderClr.blue,
255)
local zeroStr <const> = string.pack("B B B B", 0, 0, 0, 0)
---@type string[]
local byteStrs <const> = {}
local horizStripWeight <const> = cwVrf + border
local vertStripWeight <const> = chVrf + border
local horizStripArea <const> = border * horizStripWeight
local vertStripArea <const> = border * vertStripWeight
-- Draw top and bottom horizontal strips.
local i = 0
while i < horizStripArea do
local xh <const> = i % horizStripWeight
local yh <const> = i // horizStripWeight
local xTop <const> = xh
local yTop <const> = yh
local idxTop <const> = xTop + yTop * wBordered
byteStrs[1 + idxTop] = highStr
local xBtm <const> = xh + border
local yBtm <const> = yh + vertStripWeight
local idxBtm <const> = xBtm + yBtm * wBordered
byteStrs[1 + idxBtm] = highStr
i = i + 1
end
-- Draw left and right vertical strips.
local j = 0
while j < vertStripArea do
local x <const> = j % border
local y <const> = j // border
local xLft <const> = x
local yLft <const> = y + border
local idxLft <const> = xLft + yLft * wBordered
byteStrs[1 + idxLft] = highStr
local xRgt <const> = x + horizStripWeight
local yRgt <const> = y
local idxRgt <const> = xRgt + yRgt * wBordered
byteStrs[1 + idxRgt] = highStr
j = j + 1
end
-- Draw clear center.
local lenVrf <const> = cwVrf * chVrf
local k = 0
while k < lenVrf do
local x <const> = border + k % cwVrf
local y <const> = border + k // cwVrf
local idxCenter <const> = x + y * wBordered
byteStrs[1 + idxCenter] = zeroStr
k = k + 1
end
bdrImage.bytes = table.concat(byteStrs)
end
local gridGroup <const> = activeSprite:newGroup()
app.transaction("Set Grid Group Props", function()
gridGroup.name = string.format(
"Grid %d x %d",
cols, rows)
gridGroup.stackIndex = 1
gridGroup.isCollapsed = closeGroups
gridGroup.isEditable = editGrid
end)
local bkgLayer <const> = activeSprite:newLayer()
local bkgImage <const> = Image(spriteSpec)
bkgImage:clear(bkgHex)
if useBkg then
app.transaction("Set Bkg Props", function()
bkgLayer.name = "Bkg"
bkgLayer.parent = gridGroup
bkgLayer.opacity = opacity
bkgLayer.isEditable = editGrid
bkgLayer.isContinuous = oneFrame
end)
end
local headLayer = nil
local headImage = nil
if useHeader then
local headSpec <const> = ImageSpec(spriteSpec)
headSpec.width = wCellTotal * cols
+ padding * colsn1
headSpec.height = headVrf
headImage = Image(headSpec)
if headerClr.alpha > 0 then
local headHex <const> = headerClr.rgbaPixel
headImage:clear(headHex)
end
headLayer = activeSprite:newLayer()
app.transaction("Set Header Props", function()
headLayer.name = "Header"
headLayer.parent = gridGroup
headLayer.opacity = opacity
headLayer.isEditable = editGrid
headLayer.isContinuous = oneFrame
end)
end
-- Cache methods used in loops.
local floor <const> = math.floor
local strfmt <const> = string.format
local transact <const> = app.transaction
---@type Point[]
local labelPoints <const> = {}
---@type Layer[]
local labelLayers <const> = {}
---@type Point[]
local bdrPoints <const> = {}
---@type Layer[]
local bdrLayers <const> = {}
---@type Point[]
local checkPoints <const> = {}
---@type Layer[]
local checkLayers <const> = {}
local row = rows
while row > 0 do
row = row - 1
local yOffset <const> = yGridOffset + row * padding
local y <const> = row * hCellTotal + yOffset
local green <const> = floor(row * rowToGreen + 0.5)
local rowColor <const> = Color {
r = 128,
g = green,
b = 0,
a = layerColorAlpha
}
local rowGroup <const> = activeSprite:newGroup()
local rowName <const> = strfmt("Row %02d", 1 + row)
transact("Set Row Props", function()
rowGroup.name = rowName
rowGroup.parent = gridGroup
rowGroup.isCollapsed = closeGroups
rowGroup.isEditable = editGrid
rowGroup.color = rowColor
end)
transact("Create Columns", function()
local col = cols
while col > 0 do
col = col - 1
local xOffset <const> = xGridOffset + col * padding
local x <const> = col * wCellTotal + xOffset
local red <const> = floor(col * colToRed + 0.5)
local idxFlat <const> = col + row * cols
local idxReverse <const> = flatLen - idxFlat
local colColor <const> = Color {
r = red,
g = green,
b = 0,
a = layerColorAlpha
}
local colGroup <const> = activeSprite:newGroup()
colGroup.name = strfmt("Column %02d %02d", 1 + col, 1 + row)
colGroup.parent = rowGroup
colGroup.isCollapsed = closeGroups
colGroup.isEditable = editGrid
colGroup.color = colColor
if useLabel then
local labelColor <const> = Color {
r = red,
g = green,
b = layerColorBlue03,
a = layerColorAlpha
}
local labelLayer <const> = activeSprite:newLayer()
labelLayer.name = strfmt("Label %04d", 1 + idxFlat)
labelLayer.parent = colGroup
labelLayer.isContinuous = oneFrame
labelLayer.opacity = opacity
labelLayer.isEditable = editGrid
labelLayer.color = labelColor
labelPoints[idxReverse] = Point(
xLabelLoc + x,
yLabelLoc + y)
labelLayers[idxReverse] = labelLayer
end
local checkColor <const> = Color {
r = red,
g = green,
b = layerColorBlue02,
a = layerColorAlpha
}
local checkLayer <const> = activeSprite:newLayer()
checkLayer.name = strfmt("Checker %04d", 1 + idxFlat)
checkLayer.parent = colGroup
checkLayer.isContinuous = oneFrame
checkLayer.isEditable = editGrid
checkLayer.opacity = opacity
checkLayer.color = checkColor
checkPoints[idxReverse] = Point(
xLabelDisplace + border + x,
yLabelDisplace + border + y)
checkLayers[idxReverse] = checkLayer
if useBdr then
local bdrColor <const> = Color {
r = red,
g = green,
b = layerColorBlue01,
a = layerColorAlpha
}
local bdrLayer <const> = activeSprite:newLayer()
bdrLayer.name = strfmt("Border %04d", 1 + idxFlat)
bdrLayer.parent = colGroup
bdrLayer.isContinuous = oneFrame
bdrLayer.opacity = opacity
bdrLayer.isEditable = editGrid
bdrLayer.color = bdrColor
bdrPoints[idxReverse] = Point(
xLabelDisplace + x,
yLabelDisplace + y)
bdrLayers[idxReverse] = bdrLayer
end
end
end)
end
local firstFrame <const> = activeSprite.frames[1]
local duration <const> = 1.0 / math.max(1, fps)
if not oneFrame then
app.transaction("Create Frames", function()
firstFrame.duration = duration
local g = 1
while g < frameReqs do
g = g + 1
local frObj <const> = activeSprite:newEmptyFrame()
frObj.duration = duration
end
end)
else
app.transaction("Set Frame Duration", function()
firstFrame.duration = duration
end)
end
local lenFrames <const> = #activeSprite.frames
local gridFlat <const> = cols * rows
if useBkg then
app.transaction("Create Bkg Cels", function()
local h = 0
while h < lenFrames do
h = h + 1
local bkgCel <const> = activeSprite:newCel(
bkgLayer, h, bkgImage)
bkgCel.zIndex = -32768
end
end)
end
if useHeader and headLayer then
local headLoc <const> = Point(margin, margin)
app.transaction("Create Header Cels", function()
local h = 0
while h < lenFrames do
h = h + 1
local headCel <const> = activeSprite:newCel(
headLayer, h, headImage, headLoc)
headCel.zIndex = -32767
end
end)
end
local i = 0
while i < gridFlat do
i = i + 1
if useLabel then
local labelPoint <const> = labelPoints[i]
local labelLayer <const> = labelLayers[i]
app.transaction("Create Label Cel", function()
local j = 0
while j < lenFrames do
j = j + 1
local labelCel <const> = activeSprite:newCel(
labelLayer, j, labelImage, labelPoint)
labelCel.zIndex = -32766
end
end)
end
local checkPoint <const> = checkPoints[i]
local checkLayer <const> = checkLayers[i]
app.transaction("Create Checker Cel", function()
local m = 0
while m < lenFrames do
m = m + 1
local checkCel <const> = activeSprite:newCel(
checkLayer, m, checkImage, checkPoint)
checkCel.zIndex = -32765
end
end)
if useBdr then
local bdrPoint <const> = bdrPoints[i]
local bdrLayer <const> = bdrLayers[i]
app.transaction("Create Border Cel", function()
local k = 0
while k < lenFrames do
k = k + 1
local bdrCel <const> = activeSprite:newCel(
bdrLayer, k, bdrImage, bdrPoint)
bdrCel.zIndex = -32764
end
end)
end
end
if genSlices then
local sliceColor = Color { r = 255, g = 255, b = 255, a = 255 }
local appPrefs <const> = app.preferences
if appPrefs then
local slicePrefs <const> = appPrefs.slices
if slicePrefs then
local prefsColor <const> = slicePrefs.default_color --[[@as Color]]
if prefsColor then
if prefsColor.alpha > 0 then
sliceColor = colorCopy(prefsColor)
end
end
end
end