pixifact 0.1.5 → 0.2.0
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.
- package/dist/compiler/builtinScenes.d.ts +2 -2
- package/dist/compiler/builtinScenes.js +1 -9
- package/dist/compiler/compileScenes.js +16 -0
- package/dist/compiler/pixiNodeSchema.d.ts +17 -7
- package/dist/compiler/pixiNodeSchema.js +219 -0
- package/dist/compiler/sceneValidation.js +13 -2
- package/dist/compiler/spec.d.ts +5 -1
- package/dist/compiler/templateParser.js +18 -10
- package/dist/compiler/templateSerializer.js +1 -0
- package/dist/compiler/typescriptCompiler.js +53 -8
- package/dist/project/index.d.ts +5 -0
- package/dist/project/index.js +22 -0
- package/dist/runtime/Control.d.ts +18 -0
- package/dist/runtime/Control.js +49 -0
- package/dist/runtime/GridContainer.d.ts +25 -0
- package/dist/runtime/GridContainer.js +115 -0
- package/dist/runtime/Group.d.ts +2 -0
- package/dist/runtime/Group.js +30 -10
- package/dist/runtime/HBoxContainer.d.ts +21 -0
- package/dist/runtime/HBoxContainer.js +74 -0
- package/dist/runtime/Image.d.ts +47 -0
- package/dist/runtime/Image.js +220 -0
- package/dist/runtime/NineImage.d.ts +22 -0
- package/dist/runtime/NineImage.js +54 -0
- package/dist/runtime/Rect.d.ts +48 -0
- package/dist/runtime/Rect.js +162 -0
- package/dist/runtime/ScrollContainer.d.ts +28 -0
- package/dist/runtime/ScrollContainer.js +370 -0
- package/dist/runtime/TileImage.d.ts +27 -0
- package/dist/runtime/TileImage.js +57 -0
- package/dist/runtime/VBoxContainer.d.ts +21 -0
- package/dist/runtime/VBoxContainer.js +74 -0
- package/dist/runtime/frameLayout.d.ts +11 -0
- package/dist/runtime/frameLayout.js +116 -0
- package/dist/runtime/frameLayoutAccessors.d.ts +4 -0
- package/dist/runtime/frameLayoutAccessors.js +7 -0
- package/dist/runtime/index.d.ts +12 -0
- package/dist/runtime/index.js +12 -0
- package/dist/runtime/stackLayout.d.ts +16 -0
- package/dist/runtime/stackLayout.js +59 -0
- package/dist/viewport.d.ts +43 -0
- package/dist/viewport.js +93 -0
- package/package.json +2 -2
- package/dist/builtin-scenes/CenterContainer.d.ts +0 -13
- package/dist/builtin-scenes/CenterContainer.js +0 -71
- package/dist/builtin-scenes/CenterContainer.scene +0 -3
- package/dist/builtin-scenes/CenterContainer.ts +0 -77
- package/dist/builtin-scenes/Control.d.ts +0 -44
- package/dist/builtin-scenes/Control.js +0 -206
- package/dist/builtin-scenes/Control.scene +0 -3
- package/dist/builtin-scenes/Control.ts +0 -233
- package/dist/builtin-scenes/FlexItem.d.ts +0 -45
- package/dist/builtin-scenes/FlexItem.js +0 -164
- package/dist/builtin-scenes/FlexItem.scene +0 -3
- package/dist/builtin-scenes/FlexItem.ts +0 -180
- package/dist/builtin-scenes/FlexLayout.d.ts +0 -29
- package/dist/builtin-scenes/FlexLayout.js +0 -358
- package/dist/builtin-scenes/FlexLayout.scene +0 -3
- package/dist/builtin-scenes/FlexLayout.ts +0 -409
- package/dist/builtin-scenes/HBoxContainer.d.ts +0 -15
- package/dist/builtin-scenes/HBoxContainer.js +0 -70
- package/dist/builtin-scenes/HBoxContainer.scene +0 -3
- package/dist/builtin-scenes/HBoxContainer.ts +0 -75
- package/dist/builtin-scenes/MarginContainer.d.ts +0 -23
- package/dist/builtin-scenes/MarginContainer.js +0 -131
- package/dist/builtin-scenes/MarginContainer.scene +0 -3
- package/dist/builtin-scenes/MarginContainer.ts +0 -139
- package/dist/builtin-scenes/VBoxContainer.d.ts +0 -15
- package/dist/builtin-scenes/VBoxContainer.js +0 -70
- package/dist/builtin-scenes/VBoxContainer.scene +0 -3
- package/dist/builtin-scenes/VBoxContainer.ts +0 -75
- package/dist/builtin-scenes/controlLayout.d.ts +0 -57
- package/dist/builtin-scenes/controlLayout.js +0 -202
- package/dist/builtin-scenes/controlLayout.ts +0 -270
|
@@ -1,202 +0,0 @@
|
|
|
1
|
-
export const defaultControlLayoutProps = {
|
|
2
|
-
minWidth: 0,
|
|
3
|
-
minHeight: 0,
|
|
4
|
-
hSize: 'content',
|
|
5
|
-
vSize: 'content',
|
|
6
|
-
stretch: 1,
|
|
7
|
-
};
|
|
8
|
-
export function measureChildren(container) {
|
|
9
|
-
const bounds = measureChildrenBounds(container);
|
|
10
|
-
return {
|
|
11
|
-
width: bounds.width,
|
|
12
|
-
height: bounds.height,
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
export function measureChildrenBounds(container) {
|
|
16
|
-
if (container.children.length === 0) {
|
|
17
|
-
return { x: 0, y: 0, width: 0, height: 0 };
|
|
18
|
-
}
|
|
19
|
-
let minX = Number.POSITIVE_INFINITY;
|
|
20
|
-
let minY = Number.POSITIVE_INFINITY;
|
|
21
|
-
let maxX = Number.NEGATIVE_INFINITY;
|
|
22
|
-
let maxY = Number.NEGATIVE_INFINITY;
|
|
23
|
-
for (const child of container.children) {
|
|
24
|
-
minX = Math.min(minX, child.x);
|
|
25
|
-
minY = Math.min(minY, child.y);
|
|
26
|
-
maxX = Math.max(maxX, child.x + child.width);
|
|
27
|
-
maxY = Math.max(maxY, child.y + child.height);
|
|
28
|
-
}
|
|
29
|
-
return {
|
|
30
|
-
x: minX,
|
|
31
|
-
y: minY,
|
|
32
|
-
width: maxX - minX,
|
|
33
|
-
height: maxY - minY,
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
export function measureControlChild(child, baseSizes) {
|
|
37
|
-
const measured = child.measureControlNaturalSize?.();
|
|
38
|
-
if (measured) {
|
|
39
|
-
return measured;
|
|
40
|
-
}
|
|
41
|
-
if (!baseSizes.has(child)) {
|
|
42
|
-
baseSizes.set(child, {
|
|
43
|
-
width: child.width,
|
|
44
|
-
height: child.height,
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
return baseSizes.get(child) ?? { width: child.width, height: child.height };
|
|
48
|
-
}
|
|
49
|
-
export function controlChildProps(child) {
|
|
50
|
-
return child.getControlLayoutProps?.() ?? defaultControlLayoutProps;
|
|
51
|
-
}
|
|
52
|
-
export function controlMinSize(child, baseSizes) {
|
|
53
|
-
const props = controlChildProps(child);
|
|
54
|
-
const natural = measureControlChild(child, baseSizes);
|
|
55
|
-
return {
|
|
56
|
-
width: Math.max(natural.width, props.minWidth),
|
|
57
|
-
height: Math.max(natural.height, props.minHeight),
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
export function setControlChildBox(child, rect) {
|
|
61
|
-
if (child.setControlLayoutBox) {
|
|
62
|
-
child.setControlLayoutBox(rect.x, rect.y, rect.width, rect.height);
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
65
|
-
child.position.set(rect.x, rect.y);
|
|
66
|
-
}
|
|
67
|
-
export function layoutStack(options) {
|
|
68
|
-
const children = options.children;
|
|
69
|
-
if (!children || children.length === 0) {
|
|
70
|
-
return;
|
|
71
|
-
}
|
|
72
|
-
const mainAxis = options.axis;
|
|
73
|
-
const cross = crossAxis(mainAxis);
|
|
74
|
-
const naturalContainer = options.naturalSize();
|
|
75
|
-
const containerWidth = options.width ?? naturalContainer.width;
|
|
76
|
-
const containerHeight = options.height ?? naturalContainer.height;
|
|
77
|
-
const containerMain = mainAxis === 'horizontal' ? containerWidth : containerHeight;
|
|
78
|
-
const containerCross = cross === 'horizontal' ? containerWidth : containerHeight;
|
|
79
|
-
const gapTotal = options.gap * Math.max(0, children.length - 1);
|
|
80
|
-
const items = children.map((child) => {
|
|
81
|
-
const props = controlChildProps(child);
|
|
82
|
-
const natural = controlMinSize(child, options.baseSizes);
|
|
83
|
-
const mainMode = mainAxis === 'horizontal' ? props.hSize : props.vSize;
|
|
84
|
-
const crossMode = cross === 'horizontal' ? props.hSize : props.vSize;
|
|
85
|
-
return {
|
|
86
|
-
child,
|
|
87
|
-
props,
|
|
88
|
-
mainMode,
|
|
89
|
-
crossMode,
|
|
90
|
-
baseMain: mainAxis === 'horizontal' ? natural.width : natural.height,
|
|
91
|
-
baseCross: cross === 'horizontal' ? natural.width : natural.height,
|
|
92
|
-
mainSize: mainAxis === 'horizontal' ? natural.width : natural.height,
|
|
93
|
-
crossSize: cross === 'horizontal' ? natural.width : natural.height,
|
|
94
|
-
};
|
|
95
|
-
});
|
|
96
|
-
const naturalMain = items.reduce((sum, item) => sum + item.baseMain, 0);
|
|
97
|
-
const freeMain = Math.max(0, containerMain - naturalMain - gapTotal);
|
|
98
|
-
const expandable = items.filter((item) => item.mainMode === 'expand');
|
|
99
|
-
const totalStretch = expandable.reduce((sum, item) => sum + item.props.stretch, 0);
|
|
100
|
-
if (totalStretch > 0) {
|
|
101
|
-
for (const item of expandable) {
|
|
102
|
-
item.mainSize = item.baseMain + freeMain * (item.props.stretch / totalStretch);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
for (const item of items) {
|
|
106
|
-
if (fillOrExpand(item.crossMode)) {
|
|
107
|
-
item.crossSize = containerCross;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
const usedMain = items.reduce((sum, item) => sum + item.mainSize, 0) + gapTotal;
|
|
111
|
-
const remainingMain = Math.max(0, containerMain - usedMain);
|
|
112
|
-
const actualGap = options.justify === 'space-between' && items.length > 1
|
|
113
|
-
? options.gap + remainingMain / (items.length - 1)
|
|
114
|
-
: options.gap;
|
|
115
|
-
let cursor = justifyOffset(options.justify, remainingMain);
|
|
116
|
-
for (const item of items) {
|
|
117
|
-
const crossFree = Math.max(0, containerCross - item.crossSize);
|
|
118
|
-
const main = cursor;
|
|
119
|
-
const crossPosition = alignOffset(options.alignCross, crossFree);
|
|
120
|
-
setControlChildBox(item.child, {
|
|
121
|
-
x: mainAxis === 'horizontal' ? main : crossPosition,
|
|
122
|
-
y: mainAxis === 'horizontal' ? crossPosition : main,
|
|
123
|
-
width: mainAxis === 'horizontal' ? item.mainSize : item.crossSize,
|
|
124
|
-
height: mainAxis === 'horizontal' ? item.crossSize : item.mainSize,
|
|
125
|
-
});
|
|
126
|
-
cursor += item.mainSize + actualGap;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
export function measureStackNaturalSize(axis, children, gap, baseSizes) {
|
|
130
|
-
if (!children || children.length === 0) {
|
|
131
|
-
return { width: 0, height: 0 };
|
|
132
|
-
}
|
|
133
|
-
const gapTotal = gap * Math.max(0, children.length - 1);
|
|
134
|
-
const sizes = children.map((child) => controlMinSize(child, baseSizes));
|
|
135
|
-
if (axis === 'horizontal') {
|
|
136
|
-
return {
|
|
137
|
-
width: sizes.reduce((sum, size) => sum + size.width, 0) + gapTotal,
|
|
138
|
-
height: sizes.reduce((max, size) => Math.max(max, size.height), 0),
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
|
-
return {
|
|
142
|
-
width: sizes.reduce((max, size) => Math.max(max, size.width), 0),
|
|
143
|
-
height: sizes.reduce((sum, size) => sum + size.height, 0) + gapTotal,
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
|
-
export function fillOrExpand(mode) {
|
|
147
|
-
return mode === 'fill' || mode === 'expand';
|
|
148
|
-
}
|
|
149
|
-
export function crossAxis(axis) {
|
|
150
|
-
return axis === 'horizontal' ? 'vertical' : 'horizontal';
|
|
151
|
-
}
|
|
152
|
-
export function alignOffset(align, available) {
|
|
153
|
-
if (align === 'center') {
|
|
154
|
-
return available / 2;
|
|
155
|
-
}
|
|
156
|
-
if (align === 'end') {
|
|
157
|
-
return available;
|
|
158
|
-
}
|
|
159
|
-
return 0;
|
|
160
|
-
}
|
|
161
|
-
export function justifyOffset(justify, available) {
|
|
162
|
-
if (justify === 'center') {
|
|
163
|
-
return available / 2;
|
|
164
|
-
}
|
|
165
|
-
if (justify === 'end') {
|
|
166
|
-
return available;
|
|
167
|
-
}
|
|
168
|
-
return 0;
|
|
169
|
-
}
|
|
170
|
-
export function parseSizeMode(value) {
|
|
171
|
-
if (value === 'fill' || value === 'expand') {
|
|
172
|
-
return value;
|
|
173
|
-
}
|
|
174
|
-
return 'content';
|
|
175
|
-
}
|
|
176
|
-
export function parseAlign(value) {
|
|
177
|
-
if (value === 'center' || value === 'end') {
|
|
178
|
-
return value;
|
|
179
|
-
}
|
|
180
|
-
return 'start';
|
|
181
|
-
}
|
|
182
|
-
export function parseJustify(value) {
|
|
183
|
-
if (value === 'center' || value === 'end' || value === 'space-between') {
|
|
184
|
-
return value;
|
|
185
|
-
}
|
|
186
|
-
return 'start';
|
|
187
|
-
}
|
|
188
|
-
export function finiteNumber(value, fallback) {
|
|
189
|
-
return Number.isFinite(value) ? value : fallback;
|
|
190
|
-
}
|
|
191
|
-
export function boxSize(value, height) {
|
|
192
|
-
if (typeof value === 'number') {
|
|
193
|
-
return {
|
|
194
|
-
width: Math.max(0, finiteNumber(value, 0)),
|
|
195
|
-
height: Math.max(0, finiteNumber(height ?? value, 0)),
|
|
196
|
-
};
|
|
197
|
-
}
|
|
198
|
-
return {
|
|
199
|
-
width: Math.max(0, finiteNumber(value.width, 0)),
|
|
200
|
-
height: Math.max(0, finiteNumber(value.height ?? value.width, 0)),
|
|
201
|
-
};
|
|
202
|
-
}
|
|
@@ -1,270 +0,0 @@
|
|
|
1
|
-
import { Container, type ContainerChild } from 'pixi.js';
|
|
2
|
-
|
|
3
|
-
export type ControlSizeMode = 'content' | 'fill' | 'expand';
|
|
4
|
-
export type ControlAlign = 'start' | 'center' | 'end';
|
|
5
|
-
export type ControlJustify = 'start' | 'center' | 'end' | 'space-between';
|
|
6
|
-
export type ControlAxis = 'horizontal' | 'vertical';
|
|
7
|
-
|
|
8
|
-
export interface Size {
|
|
9
|
-
width: number;
|
|
10
|
-
height: number;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export interface Rect extends Size {
|
|
14
|
-
x: number;
|
|
15
|
-
y: number;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export interface ControlLayoutProps {
|
|
19
|
-
minWidth: number;
|
|
20
|
-
minHeight: number;
|
|
21
|
-
hSize: ControlSizeMode;
|
|
22
|
-
vSize: ControlSizeMode;
|
|
23
|
-
stretch: number;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export type ControlLayoutChild = ContainerChild & {
|
|
27
|
-
getControlLayoutProps?: () => ControlLayoutProps;
|
|
28
|
-
measureControlNaturalSize?: () => Size;
|
|
29
|
-
setControlLayoutBox?: (x: number, y: number, width: number, height: number) => void;
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
export const defaultControlLayoutProps: ControlLayoutProps = {
|
|
33
|
-
minWidth: 0,
|
|
34
|
-
minHeight: 0,
|
|
35
|
-
hSize: 'content',
|
|
36
|
-
vSize: 'content',
|
|
37
|
-
stretch: 1,
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
export function measureChildren(container: Container): Size {
|
|
41
|
-
const bounds = measureChildrenBounds(container);
|
|
42
|
-
return {
|
|
43
|
-
width: bounds.width,
|
|
44
|
-
height: bounds.height,
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export function measureChildrenBounds(container: Container): Rect {
|
|
49
|
-
if (container.children.length === 0) {
|
|
50
|
-
return { x: 0, y: 0, width: 0, height: 0 };
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
let minX = Number.POSITIVE_INFINITY;
|
|
54
|
-
let minY = Number.POSITIVE_INFINITY;
|
|
55
|
-
let maxX = Number.NEGATIVE_INFINITY;
|
|
56
|
-
let maxY = Number.NEGATIVE_INFINITY;
|
|
57
|
-
|
|
58
|
-
for (const child of container.children) {
|
|
59
|
-
minX = Math.min(minX, child.x);
|
|
60
|
-
minY = Math.min(minY, child.y);
|
|
61
|
-
maxX = Math.max(maxX, child.x + child.width);
|
|
62
|
-
maxY = Math.max(maxY, child.y + child.height);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
return {
|
|
66
|
-
x: minX,
|
|
67
|
-
y: minY,
|
|
68
|
-
width: maxX - minX,
|
|
69
|
-
height: maxY - minY,
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export function measureControlChild(child: ControlLayoutChild, baseSizes: WeakMap<object, Size>): Size {
|
|
74
|
-
const measured = child.measureControlNaturalSize?.();
|
|
75
|
-
if (measured) {
|
|
76
|
-
return measured;
|
|
77
|
-
}
|
|
78
|
-
if (!baseSizes.has(child)) {
|
|
79
|
-
baseSizes.set(child, {
|
|
80
|
-
width: child.width,
|
|
81
|
-
height: child.height,
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
return baseSizes.get(child) ?? { width: child.width, height: child.height };
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export function controlChildProps(child: ControlLayoutChild): ControlLayoutProps {
|
|
88
|
-
return child.getControlLayoutProps?.() ?? defaultControlLayoutProps;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
export function controlMinSize(child: ControlLayoutChild, baseSizes: WeakMap<object, Size>): Size {
|
|
92
|
-
const props = controlChildProps(child);
|
|
93
|
-
const natural = measureControlChild(child, baseSizes);
|
|
94
|
-
return {
|
|
95
|
-
width: Math.max(natural.width, props.minWidth),
|
|
96
|
-
height: Math.max(natural.height, props.minHeight),
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
export function setControlChildBox(child: ControlLayoutChild, rect: Rect) {
|
|
101
|
-
if (child.setControlLayoutBox) {
|
|
102
|
-
child.setControlLayoutBox(rect.x, rect.y, rect.width, rect.height);
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
child.position.set(rect.x, rect.y);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
export interface StackLayoutOptions {
|
|
109
|
-
axis: ControlAxis;
|
|
110
|
-
children: ControlLayoutChild[] | undefined;
|
|
111
|
-
gap: number;
|
|
112
|
-
alignCross: ControlAlign;
|
|
113
|
-
justify: ControlJustify;
|
|
114
|
-
baseSizes: WeakMap<object, Size>;
|
|
115
|
-
width: number | undefined;
|
|
116
|
-
height: number | undefined;
|
|
117
|
-
naturalSize: () => Size;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
export function layoutStack(options: StackLayoutOptions) {
|
|
121
|
-
const children = options.children;
|
|
122
|
-
if (!children || children.length === 0) {
|
|
123
|
-
return;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
const mainAxis = options.axis;
|
|
127
|
-
const cross = crossAxis(mainAxis);
|
|
128
|
-
const naturalContainer = options.naturalSize();
|
|
129
|
-
const containerWidth = options.width ?? naturalContainer.width;
|
|
130
|
-
const containerHeight = options.height ?? naturalContainer.height;
|
|
131
|
-
const containerMain = mainAxis === 'horizontal' ? containerWidth : containerHeight;
|
|
132
|
-
const containerCross = cross === 'horizontal' ? containerWidth : containerHeight;
|
|
133
|
-
const gapTotal = options.gap * Math.max(0, children.length - 1);
|
|
134
|
-
const items = children.map((child) => {
|
|
135
|
-
const props = controlChildProps(child);
|
|
136
|
-
const natural = controlMinSize(child, options.baseSizes);
|
|
137
|
-
const mainMode = mainAxis === 'horizontal' ? props.hSize : props.vSize;
|
|
138
|
-
const crossMode = cross === 'horizontal' ? props.hSize : props.vSize;
|
|
139
|
-
return {
|
|
140
|
-
child,
|
|
141
|
-
props,
|
|
142
|
-
mainMode,
|
|
143
|
-
crossMode,
|
|
144
|
-
baseMain: mainAxis === 'horizontal' ? natural.width : natural.height,
|
|
145
|
-
baseCross: cross === 'horizontal' ? natural.width : natural.height,
|
|
146
|
-
mainSize: mainAxis === 'horizontal' ? natural.width : natural.height,
|
|
147
|
-
crossSize: cross === 'horizontal' ? natural.width : natural.height,
|
|
148
|
-
};
|
|
149
|
-
});
|
|
150
|
-
const naturalMain = items.reduce((sum, item) => sum + item.baseMain, 0);
|
|
151
|
-
const freeMain = Math.max(0, containerMain - naturalMain - gapTotal);
|
|
152
|
-
const expandable = items.filter((item) => item.mainMode === 'expand');
|
|
153
|
-
const totalStretch = expandable.reduce((sum, item) => sum + item.props.stretch, 0);
|
|
154
|
-
|
|
155
|
-
if (totalStretch > 0) {
|
|
156
|
-
for (const item of expandable) {
|
|
157
|
-
item.mainSize = item.baseMain + freeMain * (item.props.stretch / totalStretch);
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
for (const item of items) {
|
|
162
|
-
if (fillOrExpand(item.crossMode)) {
|
|
163
|
-
item.crossSize = containerCross;
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
const usedMain = items.reduce((sum, item) => sum + item.mainSize, 0) + gapTotal;
|
|
168
|
-
const remainingMain = Math.max(0, containerMain - usedMain);
|
|
169
|
-
const actualGap = options.justify === 'space-between' && items.length > 1
|
|
170
|
-
? options.gap + remainingMain / (items.length - 1)
|
|
171
|
-
: options.gap;
|
|
172
|
-
let cursor = justifyOffset(options.justify, remainingMain);
|
|
173
|
-
|
|
174
|
-
for (const item of items) {
|
|
175
|
-
const crossFree = Math.max(0, containerCross - item.crossSize);
|
|
176
|
-
const main = cursor;
|
|
177
|
-
const crossPosition = alignOffset(options.alignCross, crossFree);
|
|
178
|
-
setControlChildBox(item.child, {
|
|
179
|
-
x: mainAxis === 'horizontal' ? main : crossPosition,
|
|
180
|
-
y: mainAxis === 'horizontal' ? crossPosition : main,
|
|
181
|
-
width: mainAxis === 'horizontal' ? item.mainSize : item.crossSize,
|
|
182
|
-
height: mainAxis === 'horizontal' ? item.crossSize : item.mainSize,
|
|
183
|
-
});
|
|
184
|
-
cursor += item.mainSize + actualGap;
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
export function measureStackNaturalSize(axis: ControlAxis, children: ControlLayoutChild[] | undefined, gap: number, baseSizes: WeakMap<object, Size>): Size {
|
|
189
|
-
if (!children || children.length === 0) {
|
|
190
|
-
return { width: 0, height: 0 };
|
|
191
|
-
}
|
|
192
|
-
const gapTotal = gap * Math.max(0, children.length - 1);
|
|
193
|
-
const sizes = children.map((child) => controlMinSize(child, baseSizes));
|
|
194
|
-
if (axis === 'horizontal') {
|
|
195
|
-
return {
|
|
196
|
-
width: sizes.reduce((sum, size) => sum + size.width, 0) + gapTotal,
|
|
197
|
-
height: sizes.reduce((max, size) => Math.max(max, size.height), 0),
|
|
198
|
-
};
|
|
199
|
-
}
|
|
200
|
-
return {
|
|
201
|
-
width: sizes.reduce((max, size) => Math.max(max, size.width), 0),
|
|
202
|
-
height: sizes.reduce((sum, size) => sum + size.height, 0) + gapTotal,
|
|
203
|
-
};
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
export function fillOrExpand(mode: ControlSizeMode) {
|
|
207
|
-
return mode === 'fill' || mode === 'expand';
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
export function crossAxis(axis: ControlAxis): ControlAxis {
|
|
211
|
-
return axis === 'horizontal' ? 'vertical' : 'horizontal';
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
export function alignOffset(align: ControlAlign, available: number) {
|
|
215
|
-
if (align === 'center') {
|
|
216
|
-
return available / 2;
|
|
217
|
-
}
|
|
218
|
-
if (align === 'end') {
|
|
219
|
-
return available;
|
|
220
|
-
}
|
|
221
|
-
return 0;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
export function justifyOffset(justify: ControlJustify, available: number) {
|
|
225
|
-
if (justify === 'center') {
|
|
226
|
-
return available / 2;
|
|
227
|
-
}
|
|
228
|
-
if (justify === 'end') {
|
|
229
|
-
return available;
|
|
230
|
-
}
|
|
231
|
-
return 0;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
export function parseSizeMode(value: string): ControlSizeMode {
|
|
235
|
-
if (value === 'fill' || value === 'expand') {
|
|
236
|
-
return value;
|
|
237
|
-
}
|
|
238
|
-
return 'content';
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
export function parseAlign(value: string): ControlAlign {
|
|
242
|
-
if (value === 'center' || value === 'end') {
|
|
243
|
-
return value;
|
|
244
|
-
}
|
|
245
|
-
return 'start';
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
export function parseJustify(value: string): ControlJustify {
|
|
249
|
-
if (value === 'center' || value === 'end' || value === 'space-between') {
|
|
250
|
-
return value;
|
|
251
|
-
}
|
|
252
|
-
return 'start';
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
export function finiteNumber(value: number, fallback: number) {
|
|
256
|
-
return Number.isFinite(value) ? value : fallback;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
export function boxSize(value: number | { width: number; height?: number }, height?: number): Size {
|
|
260
|
-
if (typeof value === 'number') {
|
|
261
|
-
return {
|
|
262
|
-
width: Math.max(0, finiteNumber(value, 0)),
|
|
263
|
-
height: Math.max(0, finiteNumber(height ?? value, 0)),
|
|
264
|
-
};
|
|
265
|
-
}
|
|
266
|
-
return {
|
|
267
|
-
width: Math.max(0, finiteNumber(value.width, 0)),
|
|
268
|
-
height: Math.max(0, finiteNumber(value.height ?? value.width, 0)),
|
|
269
|
-
};
|
|
270
|
-
}
|