wuira 0.2.8 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,40 +1,5 @@
1
- export declare const borderTextures: {
2
- readonly solid: {
3
- readonly label: "Solid";
4
- readonly path: "";
5
- readonly edgeSize: 1;
6
- };
7
- readonly tooltip: {
8
- readonly label: "Blizzard Tooltip";
9
- readonly path: "Interface\\Tooltips\\UI-Tooltip-Border";
10
- readonly edgeSize: 16;
11
- };
12
- readonly dialog: {
13
- readonly label: "Blizzard Dialog";
14
- readonly path: "Interface\\DialogFrame\\UI-DialogBox-Border";
15
- readonly edgeSize: 32;
16
- };
17
- readonly dialogGold: {
18
- readonly label: "Blizzard Dialog Gold";
19
- readonly path: "Interface\\DialogFrame\\UI-DialogBox-Gold-Border";
20
- readonly edgeSize: 32;
21
- };
22
- readonly achievementWood: {
23
- readonly label: "Blizzard Achievement Wood";
24
- readonly path: "Interface\\AchievementFrame\\UI-Achievement-WoodBorder";
25
- readonly edgeSize: 16;
26
- };
27
- readonly chatBubble: {
28
- readonly label: "Blizzard Chat Bubble";
29
- readonly path: "Interface\\Tooltips\\ChatBubble-Backdrop";
30
- readonly edgeSize: 16;
31
- };
32
- readonly party: {
33
- readonly label: "Blizzard Party";
34
- readonly path: "Interface\\CHARACTERFRAME\\UI-Party-Border";
35
- readonly edgeSize: 16;
36
- };
37
- };
1
+ import { borderTextures } from "../media/clientMedia";
2
+ export { borderTextures };
38
3
  export type BorderTexture = keyof typeof borderTextures | {
39
4
  path: string;
40
5
  edgeSize: number;
@@ -1,12 +1,6 @@
1
1
  --[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]
2
2
  local ____exports = {}
3
- ____exports.borderTextures = {
4
- solid = {label = "Solid", path = "", edgeSize = 1},
5
- tooltip = {label = "Blizzard Tooltip", path = "Interface\\Tooltips\\UI-Tooltip-Border", edgeSize = 16},
6
- dialog = {label = "Blizzard Dialog", path = "Interface\\DialogFrame\\UI-DialogBox-Border", edgeSize = 32},
7
- dialogGold = {label = "Blizzard Dialog Gold", path = "Interface\\DialogFrame\\UI-DialogBox-Gold-Border", edgeSize = 32},
8
- achievementWood = {label = "Blizzard Achievement Wood", path = "Interface\\AchievementFrame\\UI-Achievement-WoodBorder", edgeSize = 16},
9
- chatBubble = {label = "Blizzard Chat Bubble", path = "Interface\\Tooltips\\ChatBubble-Backdrop", edgeSize = 16},
10
- party = {label = "Blizzard Party", path = "Interface\\CHARACTERFRAME\\UI-Party-Border", edgeSize = 16}
11
- }
3
+ local ____clientMedia = require("ui.media.clientMedia")
4
+ local borderTextures = ____clientMedia.borderTextures
5
+ ____exports.borderTextures = borderTextures
12
6
  return ____exports
@@ -1,12 +1,5 @@
1
- export declare const statusBarTextures: {
2
- readonly solid: {
3
- readonly label: "Solid";
4
- readonly path: "Interface\\Buttons\\WHITE8X8";
5
- };
6
- readonly blizzard: {
7
- readonly label: "Blizzard Status Bar";
8
- readonly path: "Interface\\TargetingFrame\\UI-StatusBar";
9
- };
10
- };
11
- /** Accepts catalog names or a native/custom texture path. */
12
- export declare function resolveStatusBarTexture(texture: string): string;
1
+ export { progressTextures as statusBarTextures } from "../media/clientMedia";
2
+ /** Accepts a catalog name, a texture path, a status-bar atlas, or a numeric client file id. */
3
+ export declare function resolveStatusBarTexture(texture: string): string | number;
4
+ /** Power-bar entries from the client are atlases. A file path stays on SetStatusBarTexture. */
5
+ export declare function applyStatusBarTexture(bar: wuiraNativeStatusBar, texture: string | number): void;
@@ -1,9 +1,88 @@
1
1
  --[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]
2
+ -- Lua Library inline imports
3
+ local function __TS__StringCharCodeAt(self, index)
4
+ if index ~= index then
5
+ index = 0
6
+ end
7
+ if index < 0 then
8
+ return 0 / 0
9
+ end
10
+ return string.byte(self, index + 1) or 0 / 0
11
+ end
12
+
13
+ local function __TS__Number(value)
14
+ local valueType = type(value)
15
+ if valueType == "number" then
16
+ return value
17
+ elseif valueType == "string" then
18
+ local numberValue = tonumber(value)
19
+ if numberValue then
20
+ return numberValue
21
+ end
22
+ if value == "Infinity" then
23
+ return math.huge
24
+ end
25
+ if value == "-Infinity" then
26
+ return -math.huge
27
+ end
28
+ local stringWithoutSpaces = string.gsub(value, "%s", "")
29
+ if stringWithoutSpaces == "" then
30
+ return 0
31
+ end
32
+ return 0 / 0
33
+ elseif valueType == "boolean" then
34
+ return value and 1 or 0
35
+ else
36
+ return 0 / 0
37
+ end
38
+ end
39
+ -- End of Lua Library inline imports
2
40
  local ____exports = {}
3
- ____exports.statusBarTextures = {solid = {label = "Solid", path = "Interface\\Buttons\\WHITE8X8"}, blizzard = {label = "Blizzard Status Bar", path = "Interface\\TargetingFrame\\UI-StatusBar"}}
4
- --- Accepts catalog names or a native/custom texture path.
41
+ local ____clientMedia = require("ui.media.clientMedia")
42
+ local progressTextures = ____clientMedia.progressTextures
43
+ do
44
+ local ____clientMedia = require("ui.media.clientMedia")
45
+ ____exports.statusBarTextures = ____clientMedia.progressTextures
46
+ end
47
+ local function fileId(self, value)
48
+ if #value == 0 then
49
+ return nil
50
+ end
51
+ local index = 0
52
+ while index < #value do
53
+ local code = __TS__StringCharCodeAt(value, index)
54
+ if code < 48 or code > 57 then
55
+ return nil
56
+ end
57
+ index = index + 1
58
+ end
59
+ return __TS__Number(value)
60
+ end
61
+ --- Accepts a catalog name, a texture path, a status-bar atlas, or a numeric client file id.
5
62
  function ____exports.resolveStatusBarTexture(self, texture)
6
- local preset = ____exports.statusBarTextures[texture]
7
- return preset == nil and texture or preset.path
63
+ local preset = progressTextures[texture]
64
+ if preset ~= nil then
65
+ return preset.path
66
+ end
67
+ return fileId(nil, texture) or texture
68
+ end
69
+ local function isAtlas(self, name)
70
+ if type(GetAtlasInfo) == "function" and GetAtlasInfo(name) ~= nil then
71
+ return true
72
+ end
73
+ local textures = C_Texture
74
+ return textures ~= nil and textures.GetAtlasInfo ~= nil and textures.GetAtlasInfo(name) ~= nil
75
+ end
76
+ --- Power-bar entries from the client are atlases. A file path stays on SetStatusBarTexture.
77
+ function ____exports.applyStatusBarTexture(self, bar, texture)
78
+ if type(texture) == "string" and isAtlas(nil, texture) then
79
+ bar:SetStatusBarTexture("Interface\\Buttons\\WHITE8X8")
80
+ local fill = bar:GetStatusBarTexture()
81
+ if fill ~= nil and fill.SetAtlas ~= nil then
82
+ fill:SetAtlas(texture)
83
+ end
84
+ return
85
+ end
86
+ bar:SetStatusBarTexture(texture)
8
87
  end
9
88
  return ____exports
package/lib/ui/index.d.ts CHANGED
@@ -24,9 +24,15 @@ export { ProgressBar } from "./ProgressBar";
24
24
  export { Background } from "./decorations/Background";
25
25
  export { Border } from "./decorations/Border";
26
26
  export { Glow } from "./decorations/Glow";
27
+ export { startOverlayGlow } from "./overlayGlow";
28
+ export type { OverlayGlowKind, OverlayGlowOptions } from "./overlayGlow";
27
29
  export { Tooltip } from "./decorations/Tooltip";
28
30
  export type { TooltipProps, TooltipAnchor, TooltipLine, NativeTooltip } from "./decorations/Tooltip";
31
+ export { progressTextures, backgroundTextures, borderTextures, clientFonts } from "./media/clientMedia";
32
+ export type { ClientMedia, ClientBorder } from "./media/clientMedia";
33
+ export { resolveMediaPath } from "./media/clientMedia";
29
34
  export { Label } from "./Label";
30
35
  export type { LabelProps } from "./Label";
31
36
  export { Icon } from "./Icon";
32
37
  export type { IconProps } from "./Icon";
38
+ export { unitPortrait } from "./UnitPortrait";
package/lib/ui/index.lua CHANGED
@@ -68,10 +68,25 @@ do
68
68
  local ____Glow = require("ui.decorations.Glow")
69
69
  ____exports.Glow = ____Glow.Glow
70
70
  end
71
+ do
72
+ local ____overlayGlow = require("ui.overlayGlow")
73
+ ____exports.startOverlayGlow = ____overlayGlow.startOverlayGlow
74
+ end
71
75
  do
72
76
  local ____Tooltip = require("ui.decorations.Tooltip")
73
77
  ____exports.Tooltip = ____Tooltip.Tooltip
74
78
  end
79
+ do
80
+ local ____clientMedia = require("ui.media.clientMedia")
81
+ ____exports.progressTextures = ____clientMedia.progressTextures
82
+ ____exports.backgroundTextures = ____clientMedia.backgroundTextures
83
+ ____exports.borderTextures = ____clientMedia.borderTextures
84
+ ____exports.clientFonts = ____clientMedia.clientFonts
85
+ end
86
+ do
87
+ local ____clientMedia = require("ui.media.clientMedia")
88
+ ____exports.resolveMediaPath = ____clientMedia.resolveMediaPath
89
+ end
75
90
  do
76
91
  local ____Label = require("ui.Label")
77
92
  ____exports.Label = ____Label.Label
@@ -80,4 +95,8 @@ do
80
95
  local ____Icon = require("ui.Icon")
81
96
  ____exports.Icon = ____Icon.Icon
82
97
  end
98
+ do
99
+ local ____UnitPortrait = require("ui.UnitPortrait")
100
+ ____exports.unitPortrait = ____UnitPortrait.unitPortrait
101
+ end
83
102
  return ____exports
@@ -1,12 +1,24 @@
1
1
  import type { FlowLayoutProps } from "../FlowLayout";
2
- /** Pure layout calculation in top-left UI coordinates. */
3
- export declare function calculateFlow(props: FlowLayoutProps & {
2
+ export interface FlowChild {
4
3
  width: number;
5
4
  height: number;
6
- }, children: readonly {
5
+ anchor?: string;
6
+ }
7
+ /** Horizontal space is columnGap. Vertical space is rowGap. Older gap and lineGap fill whichever axis is unset. */
8
+ export declare function flowSpacing(direction: string | undefined, props: {
9
+ gap?: number;
10
+ lineGap?: number;
11
+ columnGap?: number;
12
+ rowGap?: number;
13
+ }): {
14
+ main: number;
15
+ cross: number;
16
+ };
17
+ /** Pack children along one direction, then place the group and each child separately. */
18
+ export declare function calculateFlow(props: FlowLayoutProps & {
7
19
  width: number;
8
20
  height: number;
9
- }[]): {
21
+ }, children: readonly FlowChild[]): {
10
22
  x: number;
11
23
  y: number;
12
24
  }[];
@@ -1,62 +1,169 @@
1
1
  --[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]
2
2
  -- Lua Library inline imports
3
- local function __TS__NumberIsFinite(value)
4
- return type(value) == "number" and value == value and value ~= math.huge and value ~= -math.huge
3
+ local function __TS__StringIncludes(self, searchString, position)
4
+ if not position then
5
+ position = 1
6
+ else
7
+ position = position + 1
8
+ end
9
+ local index = string.find(self, searchString, position, true)
10
+ return index ~= nil
11
+ end
12
+
13
+ local function __TS__ArrayMap(self, callbackfn, thisArg)
14
+ local result = {}
15
+ for i = 1, #self do
16
+ result[i] = callbackfn(thisArg, self[i], i - 1, self)
17
+ end
18
+ return result
5
19
  end
6
20
  -- End of Lua Library inline imports
7
21
  local ____exports = {}
8
- --- Pure layout calculation in top-left UI coordinates.
9
- function ____exports.calculateFlow(self, props, children)
10
- local horizontal = props.direction == "horizontal"
11
- local requestedLimit = horizontal and props.width or props.height
12
- local limit = props.sizing == "content" and requestedLimit == 0 and math.huge or requestedLimit
22
+ local function axisFraction(self, anchor, axis, fallback)
23
+ if anchor == nil or anchor == "" then
24
+ return fallback
25
+ end
26
+ if axis == "x" then
27
+ if __TS__StringIncludes(anchor, "LEFT") then
28
+ return 0
29
+ end
30
+ if __TS__StringIncludes(anchor, "RIGHT") then
31
+ return 1
32
+ end
33
+ return 0.5
34
+ end
35
+ if __TS__StringIncludes(anchor, "TOP") then
36
+ return 0
37
+ end
38
+ if __TS__StringIncludes(anchor, "BOTTOM") then
39
+ return 1
40
+ end
41
+ return 0.5
42
+ end
43
+ --- Horizontal space is columnGap. Vertical space is rowGap. Older gap and lineGap fill whichever axis is unset.
44
+ function ____exports.flowSpacing(self, direction, props)
45
+ local horizontal = direction == "horizontal" or direction == "ltr" or direction == "rtl" or direction == "horizontalReverse"
13
46
  local gap = props.gap or 0
14
47
  local lineGap = props.lineGap or gap
15
- if gap < 0 or lineGap < 0 then
48
+ local column = props.columnGap or (horizontal and gap or lineGap)
49
+ local row = props.rowGap or (horizontal and lineGap or gap)
50
+ if column < 0 or row < 0 then
16
51
  error("FlowLayout gaps must be non-negative")
17
52
  end
18
- local result = {}
19
- local cursor = 0
20
- local cross = 0
21
- local lineSize = 0
22
- local count = 0
23
- local lineStart = 0
24
- local function alignLine()
25
- local free = __TS__NumberIsFinite(limit) and math.max(0, limit - cursor) or 0
26
- local offset = props.justify == "center" and free / 2 or (props.justify == "end" and free or 0)
27
- do
28
- local index = lineStart
29
- while index < #result do
30
- if horizontal then
31
- local ____result_index_0, ____x_1 = result[index + 1], "x"
32
- ____result_index_0[____x_1] = ____result_index_0[____x_1] + offset
33
- else
34
- local ____result_index_2, ____y_3 = result[index + 1], "y"
35
- ____result_index_2[____y_3] = ____result_index_2[____y_3] + offset
36
- end
37
- index = index + 1
53
+ return horizontal and ({main = column, cross = row}) or ({main = row, cross = column})
54
+ end
55
+ local function flowAxis(self, direction)
56
+ local horizontal = direction == "horizontal" or direction == "ltr" or direction == "rtl" or direction == "horizontalReverse"
57
+ local reverse = direction == "rtl" or direction == "btt" or direction == "horizontalReverse" or direction == "verticalReverse"
58
+ return {horizontal = horizontal, reverse = reverse}
59
+ end
60
+ local function fraction(self, value, center, ____end)
61
+ if value == center then
62
+ return 0.5
63
+ end
64
+ if value == ____end then
65
+ return 1
66
+ end
67
+ return 0
68
+ end
69
+ --- Pack children along one direction, then place the group and each child separately.
70
+ function ____exports.calculateFlow(self, props, children)
71
+ local ____flowAxis_result_0 = flowAxis(nil, props.direction)
72
+ local horizontal = ____flowAxis_result_0.horizontal
73
+ local reverse = ____flowAxis_result_0.reverse
74
+ local requestedLimit = horizontal and props.width or props.height
75
+ local limit = props.sizing == "content" and requestedLimit == 0 and math.huge or requestedLimit
76
+ local spacing = ____exports.flowSpacing(nil, props.direction, props)
77
+ local gap = spacing.main
78
+ local lineGap = spacing.cross
79
+ local justifyFallback = horizontal and props.alignX == nil or not horizontal and props.alignY == nil
80
+ local ____justifyFallback_1
81
+ if justifyFallback then
82
+ ____justifyFallback_1 = props.justify
83
+ else
84
+ ____justifyFallback_1 = nil
85
+ end
86
+ local mainJustify = ____justifyFallback_1
87
+ local alignX = fraction(nil, props.alignX or (horizontal and mainJustify == "center" and "center" or (horizontal and mainJustify == "end" and "right" or nil)), "center", "right")
88
+ local alignY = fraction(nil, props.alignY or (not horizontal and mainJustify == "center" and "center" or (not horizontal and mainJustify == "end" and "bottom" or nil)), "center", "bottom")
89
+ local lines = {}
90
+ local line = {items = {}, mainSize = 0, crossSize = 0}
91
+ do
92
+ local index = 0
93
+ while index < #children do
94
+ local child = children[index + 1]
95
+ local mainSize = horizontal and child.width or child.height
96
+ local crossSize = horizontal and child.height or child.width
97
+ local next = #line.items == 0 and 0 or line.mainSize + gap
98
+ if props.grow and #line.items > 0 and next + mainSize > limit then
99
+ lines[#lines + 1] = line
100
+ line = {items = {}, mainSize = 0, crossSize = 0}
101
+ end
102
+ local main = #line.items == 0 and 0 or line.mainSize + gap
103
+ local ____line_items_2 = line.items
104
+ ____line_items_2[#____line_items_2 + 1] = {
105
+ index = index,
106
+ main = main,
107
+ mainSize = mainSize,
108
+ crossSize = crossSize,
109
+ width = child.width,
110
+ height = child.height,
111
+ anchor = child.anchor
112
+ }
113
+ line.mainSize = main + mainSize
114
+ line.crossSize = math.max(line.crossSize, crossSize)
115
+ index = index + 1
116
+ end
117
+ end
118
+ if #line.items > 0 then
119
+ lines[#lines + 1] = line
120
+ end
121
+ local packCross = 0
122
+ local packMain = 0
123
+ do
124
+ local index = 0
125
+ while index < #lines do
126
+ packMain = math.max(packMain, lines[index + 1].mainSize)
127
+ packCross = packCross + lines[index + 1].crossSize
128
+ if index < #lines - 1 then
129
+ packCross = packCross + lineGap
38
130
  end
131
+ index = index + 1
39
132
  end
40
- lineStart = #result
41
- end
42
- for ____, child in ipairs(children) do
43
- local size = horizontal and child.width or child.height
44
- local crossSize = horizontal and child.height or child.width
45
- local next = count == 0 and 0 or cursor + gap
46
- if props.grow and count > 0 and next + size > limit then
47
- alignLine(nil)
48
- cross = cross + (lineSize + lineGap)
49
- cursor = 0
50
- lineSize = 0
51
- count = 0
133
+ end
134
+ local mainBox = horizontal and (props.sizing == "content" and props.width == 0 and packMain or props.width) or (props.sizing == "content" and props.height == 0 and packMain or props.height)
135
+ local crossBox = horizontal and (props.sizing == "content" and props.height == 0 and packCross or props.height) or (props.sizing == "content" and props.width == 0 and packCross or props.width)
136
+ local mainFraction = horizontal and alignX or alignY
137
+ local crossFraction = horizontal and alignY or alignX
138
+ local result = __TS__ArrayMap(
139
+ children,
140
+ function() return {x = 0, y = 0} end
141
+ )
142
+ local cross = (crossBox - packCross) * crossFraction
143
+ do
144
+ local index = 0
145
+ while index < #lines do
146
+ local packed = lines[index + 1]
147
+ local mainFree = mainBox - packed.mainSize
148
+ local mainShift = (justifyFallback and math.max(0, mainFree) or mainFree) * mainFraction
149
+ for ____, item in ipairs(packed.items) do
150
+ local main = (reverse and packed.mainSize - item.main - item.mainSize or item.main) + mainShift
151
+ local slotX = horizontal and main or cross
152
+ local slotY = horizontal and cross or main
153
+ local slotW = horizontal and item.mainSize or packed.crossSize
154
+ local slotH = horizontal and packed.crossSize or item.mainSize
155
+ result[item.index + 1] = {
156
+ x = slotX + (slotW - item.width) * axisFraction(nil, item.anchor, "x", 0),
157
+ y = slotY + (slotH - item.height) * axisFraction(nil, item.anchor, "y", 0)
158
+ }
159
+ end
160
+ cross = cross + packed.crossSize
161
+ if index < #lines - 1 then
162
+ cross = cross + lineGap
163
+ end
164
+ index = index + 1
52
165
  end
53
- local position = count == 0 and 0 or cursor + gap
54
- result[#result + 1] = horizontal and ({x = position, y = cross}) or ({x = cross, y = position})
55
- cursor = position + size
56
- lineSize = math.max(lineSize, crossSize)
57
- count = count + 1
58
166
  end
59
- alignLine(nil)
60
167
  return result
61
168
  end
62
169
  return ____exports
@@ -1,9 +1,10 @@
1
1
  import type { GridLayoutProps } from "../GridLayout";
2
- /** Row-major placement into uniform slots; children keep their own sizes. */
3
- export declare function calculateGrid(props: GridLayoutProps, children: readonly {
4
- width: number;
5
- height: number;
6
- }[]): {
2
+ import type { FlowChild } from "./calculateFlow";
3
+ /** Place children in slots. Direction chooses the order; each child anchors inside its slot. */
4
+ export declare function calculateGrid(props: GridLayoutProps & {
5
+ width?: number;
6
+ height?: number;
7
+ }, children: readonly FlowChild[]): {
7
8
  x: number;
8
9
  y: number;
9
10
  }[];
@@ -1,5 +1,15 @@
1
1
  --[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]
2
2
  -- Lua Library inline imports
3
+ local function __TS__StringIncludes(self, searchString, position)
4
+ if not position then
5
+ position = 1
6
+ else
7
+ position = position + 1
8
+ end
9
+ local index = string.find(self, searchString, position, true)
10
+ return index ~= nil
11
+ end
12
+
3
13
  local function __TS__NumberIsFinite(value)
4
14
  return type(value) == "number" and value == value and value ~= math.huge and value ~= -math.huge
5
15
  end
@@ -13,7 +23,37 @@ local function __TS__ArrayMap(self, callbackfn, thisArg)
13
23
  end
14
24
  -- End of Lua Library inline imports
15
25
  local ____exports = {}
16
- --- Row-major placement into uniform slots; children keep their own sizes.
26
+ local function axisFraction(self, anchor, axis, fallback)
27
+ if anchor == nil or anchor == "" then
28
+ return fallback
29
+ end
30
+ if axis == "x" then
31
+ if __TS__StringIncludes(anchor, "LEFT") then
32
+ return 0
33
+ end
34
+ if __TS__StringIncludes(anchor, "RIGHT") then
35
+ return 1
36
+ end
37
+ return 0.5
38
+ end
39
+ if __TS__StringIncludes(anchor, "TOP") then
40
+ return 0
41
+ end
42
+ if __TS__StringIncludes(anchor, "BOTTOM") then
43
+ return 1
44
+ end
45
+ return 0.5
46
+ end
47
+ local function fraction(self, value, ____end)
48
+ if value == "center" then
49
+ return 0.5
50
+ end
51
+ if value == ____end then
52
+ return 1
53
+ end
54
+ return 0
55
+ end
56
+ --- Place children in slots. Direction chooses the order; each child anchors inside its slot.
17
57
  function ____exports.calculateGrid(self, props, children)
18
58
  if not __TS__NumberIsFinite(props.columns) or props.columns < 1 or math.floor(props.columns) ~= props.columns then
19
59
  error("GridLayout columns must be a positive integer")
@@ -36,12 +76,46 @@ function ____exports.calculateGrid(self, props, children)
36
76
  if width < 0 or height < 0 then
37
77
  error("GridLayout cell sizes must be non-negative")
38
78
  end
39
- return __TS__ArrayMap(
79
+ local columns = props.columns
80
+ local rows = #children == 0 and 0 or math.ceil(#children / columns)
81
+ local vertical = props.direction == "ttb" or props.direction == "btt" or props.direction == "vertical" or props.direction == "verticalReverse"
82
+ local reverse = props.direction == "rtl" or props.direction == "btt" or props.direction == "horizontalReverse" or props.direction == "verticalReverse"
83
+ local alignX = fraction(nil, props.alignX, "right")
84
+ local alignY = fraction(nil, props.alignY, "bottom")
85
+ local points = __TS__ArrayMap(
40
86
  children,
41
- function(____, _, index) return {
42
- x = index % props.columns * (width + columnGap),
43
- y = math.floor(index / props.columns) * (height + rowGap)
44
- } end
87
+ function(____, child, index)
88
+ local column = index % columns
89
+ local row = math.floor(index / columns)
90
+ if vertical then
91
+ column = math.floor(index / math.max(1, rows))
92
+ row = index % math.max(1, rows)
93
+ end
94
+ if reverse then
95
+ if vertical then
96
+ row = rows - 1 - row
97
+ else
98
+ column = columns - 1 - column
99
+ end
100
+ end
101
+ local slotX = column * (width + columnGap)
102
+ local slotY = row * (height + rowGap)
103
+ return {
104
+ x = slotX + (width - child.width) * axisFraction(nil, child.anchor, "x", 0),
105
+ y = slotY + (height - child.height) * axisFraction(nil, child.anchor, "y", 0)
106
+ }
107
+ end
45
108
  )
109
+ local packW = (columns == 0 or rows == 0) and 0 or columns * width + math.max(0, columns - 1) * columnGap
110
+ local packH = (columns == 0 or rows == 0) and 0 or rows * height + math.max(0, rows - 1) * rowGap
111
+ local boxW = props.sizing == "content" and (props.width or 0) == 0 and packW or (props.width or packW)
112
+ local boxH = props.sizing == "content" and (props.height or 0) == 0 and packH or (props.height or packH)
113
+ local shiftX = (boxW - packW) * alignX
114
+ local shiftY = (boxH - packH) * alignY
115
+ for ____, point in ipairs(points) do
116
+ point.x = point.x + shiftX
117
+ point.y = point.y + shiftY
118
+ end
119
+ return points
46
120
  end
47
121
  return ____exports