@effindomv2/fui-as 0.1.15 → 0.1.17

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.
@@ -134,6 +134,24 @@ export function createUiImportModule(deps: UiImportDeps) {
134
134
  ui_set_fill_height(handle: AppHandleLike, fill: number): void {
135
135
  deps.getRuntime().ui._ui_set_fill_height(toBigIntHandle(handle), fill);
136
136
  },
137
+ ui_set_fill_width_percent(handle: AppHandleLike, percent: number): void {
138
+ deps.getRuntime().ui._ui_set_fill_width_percent(toBigIntHandle(handle), percent);
139
+ },
140
+ ui_set_fill_height_percent(handle: AppHandleLike, percent: number): void {
141
+ deps.getRuntime().ui._ui_set_fill_height_percent(toBigIntHandle(handle), percent);
142
+ },
143
+ ui_set_min_width(handle: AppHandleLike, value: number, unit: number): void {
144
+ deps.getRuntime().ui._ui_set_min_width(toBigIntHandle(handle), value, unit);
145
+ },
146
+ ui_set_max_width(handle: AppHandleLike, value: number, unit: number): void {
147
+ deps.getRuntime().ui._ui_set_max_width(toBigIntHandle(handle), value, unit);
148
+ },
149
+ ui_set_min_height(handle: AppHandleLike, value: number, unit: number): void {
150
+ deps.getRuntime().ui._ui_set_min_height(toBigIntHandle(handle), value, unit);
151
+ },
152
+ ui_set_max_height(handle: AppHandleLike, value: number, unit: number): void {
153
+ deps.getRuntime().ui._ui_set_max_height(toBigIntHandle(handle), value, unit);
154
+ },
137
155
  ui_set_flex_direction(handle: AppHandleLike, direction: number): void {
138
156
  deps.getRuntime().ui._ui_set_flex_direction(toBigIntHandle(handle), direction);
139
157
  },
@@ -146,6 +164,9 @@ export function createUiImportModule(deps: UiImportDeps) {
146
164
  ui_set_align_items(handle: AppHandleLike, align: number): void {
147
165
  deps.getRuntime().ui._ui_set_align_items(toBigIntHandle(handle), align);
148
166
  },
167
+ ui_set_align_self(handle: AppHandleLike, align: number): void {
168
+ deps.getRuntime().ui._ui_set_align_self(toBigIntHandle(handle), align);
169
+ },
149
170
  ui_set_padding(handle: AppHandleLike, left: number, top: number, right: number, bottom: number): void {
150
171
  deps.getRuntime().ui._ui_set_padding(toBigIntHandle(handle), left, top, right, bottom);
151
172
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effindomv2/fui-as",
3
- "version": "0.1.15",
3
+ "version": "0.1.17",
4
4
  "private": false,
5
5
  "license": "AGPL-3.0-only OR LicenseRef-EffinDom-Commercial",
6
6
  "description": "EffinDom v2 AssemblyScript frontend framework SDK and browser harness",
@@ -78,7 +78,7 @@
78
78
  },
79
79
  "dependencies": {
80
80
  "@assemblyscript/loader": "^0.28.17",
81
- "@effindomv2/runtime": "0.1.5"
81
+ "@effindomv2/runtime": "0.1.6"
82
82
  },
83
83
  "devDependencies": {
84
84
  "@as-pect/assembly": "8.1.0",
package/src/Fui.ts CHANGED
@@ -69,6 +69,7 @@ export {
69
69
  export { DragCompletedEvent, DragDeltaEvent, DragGesture, DragGestureHost, DragStartedEvent } from "./core/DragGesture";
70
70
  export { ContextMenuManager } from "./core/ContextMenuManager";
71
71
  export {
72
+ AlignSelf,
72
73
  AlignItems,
73
74
  BorderStyle,
74
75
  CursorStyle,
@@ -108,6 +108,30 @@ export function setFillHeight(handle: u64, fill: bool): void {
108
108
  ffi.ui_set_fill_height(handle, fill);
109
109
  }
110
110
 
111
+ export function setFillWidthPercent(handle: u64, percent: f32): void {
112
+ ffi.ui_set_fill_width_percent(handle, percent);
113
+ }
114
+
115
+ export function setFillHeightPercent(handle: u64, percent: f32): void {
116
+ ffi.ui_set_fill_height_percent(handle, percent);
117
+ }
118
+
119
+ export function setMinWidth(handle: u64, value: f32, unit: u32): void {
120
+ ffi.ui_set_min_width(handle, value, unit);
121
+ }
122
+
123
+ export function setMaxWidth(handle: u64, value: f32, unit: u32): void {
124
+ ffi.ui_set_max_width(handle, value, unit);
125
+ }
126
+
127
+ export function setMinHeight(handle: u64, value: f32, unit: u32): void {
128
+ ffi.ui_set_min_height(handle, value, unit);
129
+ }
130
+
131
+ export function setMaxHeight(handle: u64, value: f32, unit: u32): void {
132
+ ffi.ui_set_max_height(handle, value, unit);
133
+ }
134
+
111
135
  export function setFlexDirection(handle: u64, direction: u32): void {
112
136
  ffi.ui_set_flex_direction(handle, direction);
113
137
  }
@@ -124,6 +148,10 @@ export function setAlignItems(handle: u64, align: u32): void {
124
148
  ffi.ui_set_align_items(handle, align);
125
149
  }
126
150
 
151
+ export function setAlignSelf(handle: u64, align: u32): void {
152
+ ffi.ui_set_align_self(handle, align);
153
+ }
154
+
127
155
  export function setPadding(handle: u64, left: f32, top: f32, right: f32, bottom: f32): void {
128
156
  ffi.ui_set_padding(handle, left, top, right, bottom);
129
157
  }
@@ -1,5 +1,6 @@
1
1
  import * as ui from "../bindings/ui";
2
2
  import {
3
+ AlignSelf,
3
4
  AlignItems,
4
5
  BorderStyle,
5
6
  CursorStyle,
@@ -113,7 +114,7 @@ export class Button extends FlexBox {
113
114
  private fontSizeValue: f32 = activeTheme.value.fonts.sizeBody;
114
115
  private fontIdValue: u32 = 0;
115
116
  private hasFontIdOverride: bool = false;
116
- private textColorValue: u32 = activeTheme.value.colors.textPrimary;
117
+ private textColorValue: u32 = activeTheme.value.colors.textOnAccent;
117
118
  private shadowColorValue: u32 = 0x00000000;
118
119
  private shadowOffsetXValue: f32 = 0.0;
119
120
  private shadowOffsetYValue: f32 = 0.0;
@@ -151,6 +152,7 @@ export class Button extends FlexBox {
151
152
  this.flexDirection(FlexDirection.Row);
152
153
  this.justifyContent(JustifyContent.Center);
153
154
  this.alignItems(AlignItems.Center);
155
+ this.alignSelf(AlignSelf.Start);
154
156
  this.syncThemeState(activeTheme.value);
155
157
  this.applyBackground();
156
158
  }
@@ -543,7 +545,7 @@ export class Button extends FlexBox {
543
545
  this.fontSizeValue = theme.fonts.sizeBody;
544
546
  }
545
547
  if (!this.textColorOverridden) {
546
- this.textColorValue = theme.colors.textPrimary;
548
+ this.textColorValue = theme.colors.textOnAccent;
547
549
  }
548
550
  const presenterHostState = new ButtonPresenterHostState(
549
551
  this.backgroundOverridden,
@@ -82,7 +82,7 @@ class DefaultButtonPresenter extends ButtonPresenter {
82
82
  .fontWeight(FontWeight.Regular)
83
83
  .fontStyle(FontStyle.Normal)
84
84
  .fontSize(theme.fonts.sizeBody)
85
- .textColor(theme.colors.textPrimary);
85
+ .textColor(theme.colors.textOnAccent);
86
86
  }
87
87
  }
88
88
 
@@ -95,7 +95,7 @@ class DefaultCheckboxIndicatorPresenter extends CheckboxIndicatorPresenter {
95
95
  : (state.hovered ? theme.colors.accentHovered : theme.colors.accent);
96
96
  borderColor = background;
97
97
  markVisible = state.checkedState == SemanticCheckedState.True;
98
- markColor = theme.colors.surface;
98
+ markColor = theme.colors.textOnAccent;
99
99
  } else if (state.hovered) {
100
100
  background = theme.colors.background;
101
101
  }
@@ -12,7 +12,6 @@ import { DropdownSizing } from "../ControlSizing";
12
12
 
13
13
  const DEFAULT_CHEVRON_BOX_SIZE: f32 = 16.0;
14
14
  const DEFAULT_FIELD_PADDING_X: f32 = 16.0;
15
- const DEFAULT_FIELD_PADDING_Y: f32 = 8.0;
16
15
  const DEFAULT_FIELD_FONT_SIZE: f32 = 16.0;
17
16
  const DEFAULT_FIELD_HEIGHT: f32 = 32.0;
18
17
 
@@ -33,9 +32,9 @@ const DEFAULT_DROPDOWN_FIELD_METRICS = new DropdownFieldMetrics(
33
32
  DEFAULT_FIELD_FONT_SIZE,
34
33
  DEFAULT_CHEVRON_BOX_SIZE,
35
34
  DEFAULT_FIELD_PADDING_X,
36
- DEFAULT_FIELD_PADDING_Y,
35
+ 0.0,
37
36
  DEFAULT_FIELD_PADDING_X,
38
- DEFAULT_FIELD_PADDING_Y,
37
+ 0.0,
39
38
  );
40
39
 
41
40
  function resolveFieldMetrics(sizing: DropdownSizing | null): DropdownFieldMetrics {
@@ -48,16 +47,15 @@ function resolveFieldMetrics(sizing: DropdownSizing | null): DropdownFieldMetric
48
47
  const fontSize = sizing.hasFieldFontSize ? sizing.fieldFontSizePx : DEFAULT_DROPDOWN_FIELD_METRICS.fontSize;
49
48
  const chevronBoxSize = sizing.hasChevronBoxSize ? sizing.chevronBoxSizePx : DEFAULT_DROPDOWN_FIELD_METRICS.chevronBoxSize;
50
49
  const contentHeight = fontSize > chevronBoxSize ? fontSize : chevronBoxSize;
51
- const height = sizing.hasFieldHeight ? sizing.fieldHeightPx : contentHeight + (DEFAULT_FIELD_PADDING_Y * 2.0);
52
- const verticalPadding = height > contentHeight ? (height - contentHeight) * 0.5 : 0.0;
50
+ const height = sizing.hasFieldHeight ? sizing.fieldHeightPx : <f32>Math.max(DEFAULT_DROPDOWN_FIELD_METRICS.height, contentHeight);
53
51
  return new DropdownFieldMetrics(
54
52
  height,
55
53
  fontSize,
56
54
  chevronBoxSize,
57
55
  DEFAULT_FIELD_PADDING_X,
58
- verticalPadding,
56
+ 0.0,
59
57
  DEFAULT_FIELD_PADDING_X,
60
- verticalPadding,
58
+ 0.0,
61
59
  );
62
60
  }
63
61
 
@@ -135,6 +133,10 @@ class DefaultDropdownFieldPresenter extends DropdownFieldPresenter {
135
133
 
136
134
  apply(theme: Theme, state: DropdownFieldVisualState): void {
137
135
  const metrics = this.metrics;
136
+ const contentHeight = <f32>Math.max(
137
+ metrics.fontSize,
138
+ metrics.height - metrics.paddingTop - metrics.paddingBottom,
139
+ );
138
140
  this.root
139
141
  .flexDirection(FlexDirection.Row)
140
142
  .alignItems(AlignItems.Center)
@@ -144,10 +146,10 @@ class DefaultDropdownFieldPresenter extends DropdownFieldPresenter {
144
146
  .padding(metrics.paddingLeft, metrics.paddingTop, metrics.paddingRight, metrics.paddingBottom)
145
147
  .bgColor(state.pressed && state.enabled ? theme.colors.background : theme.colors.surface);
146
148
  this.valueHost
147
- .fillWidth()
148
- .fillHeight();
149
+ .fillSize();
149
150
  this.valueNode
150
151
  .font(theme.fonts.body, metrics.fontSize)
152
+ .lineHeight(contentHeight)
151
153
  .textColor(state.enabled ? theme.colors.textPrimary : theme.colors.textMuted);
152
154
  this.chevronHost
153
155
  .width(metrics.chevronBoxSize, Unit.Pixel)
@@ -123,6 +123,10 @@ export function getTextureAssetHeight(textureId: u32): f32 {
123
123
  return getAssetRecord(textureAssets, textureId).height;
124
124
  }
125
125
 
126
+ export function markTextureAssetReady(textureId: u32, width: f32, height: f32): void {
127
+ markLoaded(getAssetRecord(textureAssets, textureId), width, height);
128
+ }
129
+
126
130
  function loadSvgInternal(svgId: u32, url: string, pinned: bool): void {
127
131
  const record = getAssetRecord(svgAssets, svgId);
128
132
  if (record.url.length > 0 && record.url != url) {
@@ -1,4 +1,5 @@
1
1
  import * as ui from "../bindings/ui";
2
+ import { markTextureAssetReady } from "./Assets";
2
3
  import { Disposable } from "./Disposable";
3
4
  import { allocateDynamicTextureId } from "./DynamicAssetIds";
4
5
  import { throwObjectDisposed } from "./Errors";
@@ -50,6 +51,7 @@ export class Bitmap implements Disposable {
50
51
  commit(): u32 {
51
52
  this.ensureNotDisposed("Bitmap.commit");
52
53
  ui.bitmapCommit(this.textureId, this.pixelBytes, this.width, this.height);
54
+ markTextureAssetReady(this.textureId, <f32>this.width, <f32>this.height);
53
55
  return this.textureId;
54
56
  }
55
57
 
package/src/core/Theme.ts CHANGED
@@ -29,6 +29,7 @@ export class Colors {
29
29
  readonly surface: u32,
30
30
  readonly textPrimary: u32,
31
31
  readonly textMuted: u32,
32
+ readonly textOnAccent: u32,
32
33
  readonly accent: u32,
33
34
  readonly accentPressed: u32,
34
35
  readonly accentHovered: u32,
@@ -184,6 +185,14 @@ function normalizeAccentColor(color: u32): u32 {
184
185
  return normalized;
185
186
  }
186
187
 
188
+ function pickAccentForeground(accent: u32): u32 {
189
+ const brightness =
190
+ (<f32>colorRed(accent) * 0.2126) +
191
+ (<f32>colorGreen(accent) * 0.7152) +
192
+ (<f32>colorBlue(accent) * 0.0722);
193
+ return brightness < 160.0 ? WHITE : BLACK;
194
+ }
195
+
187
196
  function estimateThemeDark(theme: Theme): bool {
188
197
  const background = theme.colors.background;
189
198
  const luminance =
@@ -218,6 +227,7 @@ export function generateTheme(isDark: bool, accentColor: u32 = DEFAULT_ACCENT_CO
218
227
  const surface = isDark ? rgb(0x0f, 0x17, 0x28) : rgb(0xff, 0xff, 0xff);
219
228
  const textPrimary = isDark ? rgb(0xf8, 0xfa, 0xfc) : rgb(0x0f, 0x17, 0x2a);
220
229
  const textMuted = isDark ? rgb(0x94, 0xa3, 0xb8) : rgb(0x47, 0x55, 0x69);
230
+ const textOnAccent = pickAccentForeground(accent);
221
231
  const border = isDark ? rgb(0x24, 0x3b, 0x53) : rgb(0xcb, 0xd5, 0xe1);
222
232
  const accentHovered = isDark
223
233
  ? mixColor(accent, WHITE, 0.14)
@@ -250,6 +260,7 @@ export function generateTheme(isDark: bool, accentColor: u32 = DEFAULT_ACCENT_CO
250
260
  surface,
251
261
  textPrimary,
252
262
  textMuted,
263
+ textOnAccent,
253
264
  accent,
254
265
  accentPressed,
255
266
  accentHovered,
package/src/core/ffi.ts CHANGED
@@ -60,6 +60,14 @@ export enum AlignItems {
60
60
  Stretch = 4,
61
61
  }
62
62
 
63
+ export enum AlignSelf {
64
+ Auto = 0,
65
+ Start = 1,
66
+ Center = 2,
67
+ End = 3,
68
+ Stretch = 4,
69
+ }
70
+
63
71
  export enum BorderStyle {
64
72
  Solid = 0,
65
73
  Dashed = 1,
@@ -234,6 +242,24 @@ export declare function ui_set_fill_width(handle: u64, fill: bool): void;
234
242
  @external("effindom_v2_ui", "ui_set_fill_height")
235
243
  export declare function ui_set_fill_height(handle: u64, fill: bool): void;
236
244
 
245
+ @external("effindom_v2_ui", "ui_set_fill_width_percent")
246
+ export declare function ui_set_fill_width_percent(handle: u64, percent: f32): void;
247
+
248
+ @external("effindom_v2_ui", "ui_set_fill_height_percent")
249
+ export declare function ui_set_fill_height_percent(handle: u64, percent: f32): void;
250
+
251
+ @external("effindom_v2_ui", "ui_set_min_width")
252
+ export declare function ui_set_min_width(handle: u64, value: f32, unit: u32): void;
253
+
254
+ @external("effindom_v2_ui", "ui_set_max_width")
255
+ export declare function ui_set_max_width(handle: u64, value: f32, unit: u32): void;
256
+
257
+ @external("effindom_v2_ui", "ui_set_min_height")
258
+ export declare function ui_set_min_height(handle: u64, value: f32, unit: u32): void;
259
+
260
+ @external("effindom_v2_ui", "ui_set_max_height")
261
+ export declare function ui_set_max_height(handle: u64, value: f32, unit: u32): void;
262
+
237
263
  @external("effindom_v2_ui", "ui_set_flex_direction")
238
264
  export declare function ui_set_flex_direction(handle: u64, direction: u32): void;
239
265
 
@@ -246,6 +272,9 @@ export declare function ui_set_justify_content(handle: u64, justify: u32): void;
246
272
  @external("effindom_v2_ui", "ui_set_align_items")
247
273
  export declare function ui_set_align_items(handle: u64, align: u32): void;
248
274
 
275
+ @external("effindom_v2_ui", "ui_set_align_self")
276
+ export declare function ui_set_align_self(handle: u64, align: u32): void;
277
+
249
278
  @external("effindom_v2_ui", "ui_set_padding")
250
279
  export declare function ui_set_padding(handle: u64, left: f32, top: f32, right: f32, bottom: f32): void;
251
280
 
@@ -10,6 +10,7 @@ import { warn } from "../core/Logger";
10
10
  import { throwNullArgument } from "../core/Errors";
11
11
  import { NodeTransitions } from "../core/Transitions";
12
12
  import {
13
+ AlignSelf,
13
14
  AlignItems,
14
15
  BorderStyle,
15
16
  FlexDirection,
@@ -39,10 +40,26 @@ export class FlexBoxProps {
39
40
  widthUnit: Unit = Unit.Pixel;
40
41
  hasWidth: bool = false;
41
42
  hasFillWidth: bool = false;
43
+ fillWidthPercentValue: f32 = 0.0;
44
+ hasFillWidthPercent: bool = false;
42
45
  heightValue: f32 = 0.0;
43
46
  heightUnit: Unit = Unit.Pixel;
44
47
  hasHeight: bool = false;
45
48
  hasFillHeight: bool = false;
49
+ fillHeightPercentValue: f32 = 0.0;
50
+ hasFillHeightPercent: bool = false;
51
+ minWidthValue: f32 = 0.0;
52
+ minWidthUnit: Unit = Unit.Auto;
53
+ hasMinWidth: bool = false;
54
+ maxWidthValue: f32 = 0.0;
55
+ maxWidthUnit: Unit = Unit.Auto;
56
+ hasMaxWidth: bool = false;
57
+ minHeightValue: f32 = 0.0;
58
+ minHeightUnit: Unit = Unit.Auto;
59
+ hasMinHeight: bool = false;
60
+ maxHeightValue: f32 = 0.0;
61
+ maxHeightUnit: Unit = Unit.Auto;
62
+ hasMaxHeight: bool = false;
46
63
  flexBasisValue: f32 = 0.0;
47
64
  hasFlexBasis: bool = false;
48
65
  backgroundColor: u32 = 0;
@@ -53,6 +70,8 @@ export class FlexBoxProps {
53
70
  hasJustifyContent: bool = false;
54
71
  alignItemsValue: AlignItems = AlignItems.Start;
55
72
  hasAlignItems: bool = false;
73
+ alignSelfValue: AlignSelf = AlignSelf.Auto;
74
+ hasAlignSelf: bool = false;
56
75
  paddingTop: f32 = 0.0;
57
76
  paddingRight: f32 = 0.0;
58
77
  paddingBottom: f32 = 0.0;
@@ -73,10 +92,26 @@ export class FlexBox extends Node {
73
92
  private widthUnit: Unit = Unit.Pixel;
74
93
  private hasWidth: bool = false;
75
94
  private hasFillWidth: bool = false;
95
+ private fillWidthPercentValue: f32 = 0.0;
96
+ private hasFillWidthPercent: bool = false;
76
97
  private heightValue: f32 = 0.0;
77
98
  private heightUnit: Unit = Unit.Pixel;
78
99
  private hasHeight: bool = false;
79
100
  private hasFillHeight: bool = false;
101
+ private fillHeightPercentValue: f32 = 0.0;
102
+ private hasFillHeightPercent: bool = false;
103
+ private minWidthValue: f32 = 0.0;
104
+ private minWidthUnit: Unit = Unit.Auto;
105
+ private hasMinWidth: bool = false;
106
+ private maxWidthValue: f32 = 0.0;
107
+ private maxWidthUnit: Unit = Unit.Auto;
108
+ private hasMaxWidth: bool = false;
109
+ private minHeightValue: f32 = 0.0;
110
+ private minHeightUnit: Unit = Unit.Auto;
111
+ private hasMinHeight: bool = false;
112
+ private maxHeightValue: f32 = 0.0;
113
+ private maxHeightUnit: Unit = Unit.Auto;
114
+ private hasMaxHeight: bool = false;
80
115
  private flexBasisValue: f32 = 0.0;
81
116
  private hasFlexBasis: bool = false;
82
117
  private backgroundColor: u32 = 0;
@@ -97,6 +132,8 @@ export class FlexBox extends Node {
97
132
  private hasJustifyContent: bool = false;
98
133
  private alignItemsValue: AlignItems = AlignItems.Start;
99
134
  private hasAlignItems: bool = false;
135
+ private alignSelfValue: AlignSelf = AlignSelf.Auto;
136
+ private hasAlignSelf: bool = false;
100
137
  private paddingTop: f32 = 0.0;
101
138
  private paddingRight: f32 = 0.0;
102
139
  private paddingBottom: f32 = 0.0;
@@ -150,6 +187,7 @@ export class FlexBox extends Node {
150
187
  this.widthUnit = unit;
151
188
  this.hasWidth = true;
152
189
  this.hasFillWidth = false;
190
+ this.hasFillWidthPercent = false;
153
191
  if (this.hasBuiltHandle()) {
154
192
  ui.setWidth(this.handle, value, <u32>unit);
155
193
  this.notifyRetainedLayoutMutation();
@@ -162,6 +200,7 @@ export class FlexBox extends Node {
162
200
  this.heightUnit = unit;
163
201
  this.hasHeight = true;
164
202
  this.hasFillHeight = false;
203
+ this.hasFillHeightPercent = false;
165
204
  if (this.hasBuiltHandle()) {
166
205
  ui.setHeight(this.handle, value, <u32>unit);
167
206
  this.notifyRetainedLayoutMutation();
@@ -170,7 +209,9 @@ export class FlexBox extends Node {
170
209
  }
171
210
 
172
211
  fillWidth(): this {
212
+ this.hasWidth = false;
173
213
  this.hasFillWidth = true;
214
+ this.hasFillWidthPercent = false;
174
215
  if (this.hasBuiltHandle()) {
175
216
  ui.setFillWidth(this.handle, true);
176
217
  this.notifyRetainedLayoutMutation();
@@ -179,7 +220,9 @@ export class FlexBox extends Node {
179
220
  }
180
221
 
181
222
  fillHeight(): this {
223
+ this.hasHeight = false;
182
224
  this.hasFillHeight = true;
225
+ this.hasFillHeightPercent = false;
183
226
  if (this.hasBuiltHandle()) {
184
227
  ui.setFillHeight(this.handle, true);
185
228
  this.notifyRetainedLayoutMutation();
@@ -187,6 +230,74 @@ export class FlexBox extends Node {
187
230
  return this;
188
231
  }
189
232
 
233
+ fillWidthPercent(percent: f32): this {
234
+ this.hasWidth = false;
235
+ this.hasFillWidth = false;
236
+ this.hasFillWidthPercent = true;
237
+ this.fillWidthPercentValue = percent;
238
+ if (this.hasBuiltHandle()) {
239
+ ui.setFillWidthPercent(this.handle, percent);
240
+ this.notifyRetainedLayoutMutation();
241
+ }
242
+ return this;
243
+ }
244
+
245
+ fillHeightPercent(percent: f32): this {
246
+ this.hasHeight = false;
247
+ this.hasFillHeight = false;
248
+ this.hasFillHeightPercent = true;
249
+ this.fillHeightPercentValue = percent;
250
+ if (this.hasBuiltHandle()) {
251
+ ui.setFillHeightPercent(this.handle, percent);
252
+ this.notifyRetainedLayoutMutation();
253
+ }
254
+ return this;
255
+ }
256
+
257
+ minWidth(value: f32, unit: Unit = Unit.Pixel): this {
258
+ this.minWidthValue = value;
259
+ this.minWidthUnit = unit;
260
+ this.hasMinWidth = unit != Unit.Auto;
261
+ if (this.hasBuiltHandle()) {
262
+ ui.setMinWidth(this.handle, value, <u32>unit);
263
+ this.notifyRetainedLayoutMutation();
264
+ }
265
+ return this;
266
+ }
267
+
268
+ maxWidth(value: f32, unit: Unit = Unit.Pixel): this {
269
+ this.maxWidthValue = value;
270
+ this.maxWidthUnit = unit;
271
+ this.hasMaxWidth = unit != Unit.Auto;
272
+ if (this.hasBuiltHandle()) {
273
+ ui.setMaxWidth(this.handle, value, <u32>unit);
274
+ this.notifyRetainedLayoutMutation();
275
+ }
276
+ return this;
277
+ }
278
+
279
+ minHeight(value: f32, unit: Unit = Unit.Pixel): this {
280
+ this.minHeightValue = value;
281
+ this.minHeightUnit = unit;
282
+ this.hasMinHeight = unit != Unit.Auto;
283
+ if (this.hasBuiltHandle()) {
284
+ ui.setMinHeight(this.handle, value, <u32>unit);
285
+ this.notifyRetainedLayoutMutation();
286
+ }
287
+ return this;
288
+ }
289
+
290
+ maxHeight(value: f32, unit: Unit = Unit.Pixel): this {
291
+ this.maxHeightValue = value;
292
+ this.maxHeightUnit = unit;
293
+ this.hasMaxHeight = unit != Unit.Auto;
294
+ if (this.hasBuiltHandle()) {
295
+ ui.setMaxHeight(this.handle, value, <u32>unit);
296
+ this.notifyRetainedLayoutMutation();
297
+ }
298
+ return this;
299
+ }
300
+
190
301
  fillSize(): this {
191
302
  this.fillWidth();
192
303
  this.fillHeight();
@@ -304,6 +415,16 @@ export class FlexBox extends Node {
304
415
  return this;
305
416
  }
306
417
 
418
+ alignSelf(align: AlignSelf): this {
419
+ this.alignSelfValue = align;
420
+ this.hasAlignSelf = true;
421
+ if (this.hasBuiltHandle()) {
422
+ ui.setAlignSelf(this.handle, <u32>align);
423
+ this.notifyRetainedMutation();
424
+ }
425
+ return this;
426
+ }
427
+
307
428
  padding(left: f32, top: f32, right: f32, bottom: f32): this {
308
429
  this.paddingLeft = left;
309
430
  this.paddingTop = top;
@@ -528,12 +649,30 @@ export class FlexBox extends Node {
528
649
  if (this.hasFillWidth) {
529
650
  ui.setFillWidth(this.handle, true);
530
651
  }
652
+ if (this.hasFillWidthPercent) {
653
+ ui.setFillWidthPercent(this.handle, this.fillWidthPercentValue);
654
+ }
531
655
  if (this.hasHeight) {
532
656
  ui.setHeight(this.handle, this.heightValue, <u32>this.heightUnit);
533
657
  }
534
658
  if (this.hasFillHeight) {
535
659
  ui.setFillHeight(this.handle, true);
536
660
  }
661
+ if (this.hasFillHeightPercent) {
662
+ ui.setFillHeightPercent(this.handle, this.fillHeightPercentValue);
663
+ }
664
+ if (this.hasMinWidth) {
665
+ ui.setMinWidth(this.handle, this.minWidthValue, <u32>this.minWidthUnit);
666
+ }
667
+ if (this.hasMaxWidth) {
668
+ ui.setMaxWidth(this.handle, this.maxWidthValue, <u32>this.maxWidthUnit);
669
+ }
670
+ if (this.hasMinHeight) {
671
+ ui.setMinHeight(this.handle, this.minHeightValue, <u32>this.minHeightUnit);
672
+ }
673
+ if (this.hasMaxHeight) {
674
+ ui.setMaxHeight(this.handle, this.maxHeightValue, <u32>this.maxHeightUnit);
675
+ }
537
676
  if (this.hasFlexDirection) {
538
677
  ui.setFlexDirection(this.handle, <u32>this.flexDirectionValue);
539
678
  }
@@ -546,6 +685,9 @@ export class FlexBox extends Node {
546
685
  if (this.hasAlignItems) {
547
686
  ui.setAlignItems(this.handle, <u32>this.alignItemsValue);
548
687
  }
688
+ if (this.hasAlignSelf) {
689
+ ui.setAlignSelf(this.handle, <u32>this.alignSelfValue);
690
+ }
549
691
  if (this.hasMargin) {
550
692
  ui.setMargin(this.handle, this.marginLeft, this.marginTop, this.marginRight, this.marginBottom);
551
693
  }
@@ -570,12 +712,30 @@ export class FlexBox extends Node {
570
712
  if (props.hasFillWidth) {
571
713
  this.fillWidth();
572
714
  }
715
+ if (props.hasFillWidthPercent) {
716
+ this.fillWidthPercent(props.fillWidthPercentValue);
717
+ }
573
718
  if (props.hasHeight) {
574
719
  this.height(props.heightValue, props.heightUnit);
575
720
  }
576
721
  if (props.hasFillHeight) {
577
722
  this.fillHeight();
578
723
  }
724
+ if (props.hasFillHeightPercent) {
725
+ this.fillHeightPercent(props.fillHeightPercentValue);
726
+ }
727
+ if (props.hasMinWidth) {
728
+ this.minWidth(props.minWidthValue, props.minWidthUnit);
729
+ }
730
+ if (props.hasMaxWidth) {
731
+ this.maxWidth(props.maxWidthValue, props.maxWidthUnit);
732
+ }
733
+ if (props.hasMinHeight) {
734
+ this.minHeight(props.minHeightValue, props.minHeightUnit);
735
+ }
736
+ if (props.hasMaxHeight) {
737
+ this.maxHeight(props.maxHeightValue, props.maxHeightUnit);
738
+ }
579
739
  if (props.hasFlexBasis) {
580
740
  this.flexBasis(props.flexBasisValue);
581
741
  }
@@ -591,6 +751,9 @@ export class FlexBox extends Node {
591
751
  if (props.hasAlignItems) {
592
752
  this.alignItems(props.alignItemsValue);
593
753
  }
754
+ if (props.hasAlignSelf) {
755
+ this.alignSelf(props.alignSelfValue);
756
+ }
594
757
  if (props.hasPadding) {
595
758
  this.padding(props.paddingLeft, props.paddingTop, props.paddingRight, props.paddingBottom);
596
759
  }
@@ -8,8 +8,9 @@ import {
8
8
  getTextureAssetWidth,
9
9
  releaseTextureAsset,
10
10
  } from "../core/Assets";
11
+ import { Action, HandlerAction } from "../core/Action";
11
12
  import * as ui from "../bindings/ui";
12
- import { HandleValue, NodeType, ObjectFit, SemanticRole } from "../core/ffi";
13
+ import { HandleValue, NodeType, ObjectFit, SemanticRole, Unit } from "../core/ffi";
13
14
  import { Signal } from "../core/Signal";
14
15
  import { FlexBox, FlexBoxProps } from "./FlexBox";
15
16
 
@@ -23,11 +24,20 @@ export class Image extends FlexBox {
23
24
  private insetTop: f32 = 0.0;
24
25
  private insetRight: f32 = 0.0;
25
26
  private insetBottom: f32 = 0.0;
27
+ private requestedWidthValue: f32 = 0.0;
28
+ private requestedWidthUnit: Unit = Unit.Pixel;
29
+ private hasRequestedWidth: bool = false;
30
+ private requestedHeightValue: f32 = 0.0;
31
+ private requestedHeightUnit: Unit = Unit.Pixel;
32
+ private hasRequestedHeight: bool = false;
33
+ private assetStateAction: Action<AssetLoadState> | null = null;
34
+ private trackedTextureAssetId: u32 = 0;
26
35
 
27
36
  constructor(textureId: u32 = 0, objectFit: ObjectFit = ObjectFit.Fill) {
28
37
  super();
29
38
  this.textureIdValue = textureId;
30
39
  this.objectFitValue = objectFit;
40
+ this.attachAssetStateListener();
31
41
  }
32
42
 
33
43
  static from(props: FlexBoxProps, textureId: u32 = 0, objectFit: ObjectFit = ObjectFit.Fill): Image {
@@ -47,6 +57,8 @@ export class Image extends FlexBox {
47
57
  this.releaseOwnedSourceAsset();
48
58
  this.sourceUrlValue = "";
49
59
  this.textureIdValue = textureId;
60
+ this.attachAssetStateListener();
61
+ this.applyResolvedSizing();
50
62
  if (this.hasBuiltHandle()) {
51
63
  this.applyImageSource();
52
64
  this.notifyRetainedMutation();
@@ -65,6 +77,8 @@ export class Image extends FlexBox {
65
77
  this.sourceUrlValue = url;
66
78
  this.textureIdValue = acquireTextureAsset(url);
67
79
  this.ownedTextureAssetId = this.textureIdValue;
80
+ this.attachAssetStateListener();
81
+ this.applyResolvedSizing();
68
82
  if (this.hasBuiltHandle()) {
69
83
  this.applyImageSource();
70
84
  this.notifyRetainedMutation();
@@ -81,6 +95,8 @@ export class Image extends FlexBox {
81
95
  this.insetTop = 0.0;
82
96
  this.insetRight = 0.0;
83
97
  this.insetBottom = 0.0;
98
+ this.attachAssetStateListener();
99
+ this.applyResolvedSizing();
84
100
  if (this.hasBuiltHandle()) {
85
101
  this.applyImageSource();
86
102
  this.notifyRetainedMutation();
@@ -129,13 +145,31 @@ export class Image extends FlexBox {
129
145
  return this;
130
146
  }
131
147
 
148
+ width(value: f32, unit: Unit = Unit.Pixel): this {
149
+ this.requestedWidthValue = value;
150
+ this.requestedWidthUnit = unit;
151
+ this.hasRequestedWidth = true;
152
+ this.applyResolvedSizing();
153
+ return this;
154
+ }
155
+
156
+ height(value: f32, unit: Unit = Unit.Pixel): this {
157
+ this.requestedHeightValue = value;
158
+ this.requestedHeightUnit = unit;
159
+ this.hasRequestedHeight = true;
160
+ this.applyResolvedSizing();
161
+ return this;
162
+ }
163
+
132
164
  build(): u64 {
133
165
  this.buildStyledNode(NodeType.Image, false);
166
+ this.applyResolvedSizing();
134
167
  this.applyImageSource();
135
168
  return this.handle;
136
169
  }
137
170
 
138
171
  dispose(): void {
172
+ this.detachAssetStateListener();
139
173
  this.releaseOwnedSourceAsset();
140
174
  super.dispose();
141
175
  }
@@ -179,6 +213,68 @@ export class Image extends FlexBox {
179
213
  ui.setImage(this.handle, this.textureIdValue, <u32>this.objectFitValue);
180
214
  }
181
215
 
216
+ private applyResolvedSizing(): void {
217
+ if (!this.hasRequestedWidth && !this.hasRequestedHeight) {
218
+ return;
219
+ }
220
+
221
+ const assetWidth = this.assetWidth();
222
+ const assetHeight = this.assetHeight();
223
+ const hasIntrinsicSize = assetWidth > 0.0 && assetHeight > 0.0;
224
+
225
+ if (this.hasRequestedWidth) {
226
+ let resolvedWidthValue = this.requestedWidthValue;
227
+ let resolvedWidthUnit = this.requestedWidthUnit;
228
+ if (this.requestedWidthUnit == Unit.Auto && hasIntrinsicSize) {
229
+ if (this.hasRequestedHeight && this.requestedHeightUnit == Unit.Pixel) {
230
+ resolvedWidthValue = this.requestedHeightValue * (assetWidth / assetHeight);
231
+ } else {
232
+ resolvedWidthValue = assetWidth;
233
+ }
234
+ resolvedWidthUnit = Unit.Pixel;
235
+ }
236
+ super.width(resolvedWidthValue, resolvedWidthUnit);
237
+ }
238
+
239
+ if (this.hasRequestedHeight) {
240
+ let resolvedHeightValue = this.requestedHeightValue;
241
+ let resolvedHeightUnit = this.requestedHeightUnit;
242
+ if (this.requestedHeightUnit == Unit.Auto && hasIntrinsicSize) {
243
+ if (this.hasRequestedWidth && this.requestedWidthUnit == Unit.Pixel) {
244
+ resolvedHeightValue = this.requestedWidthValue * (assetHeight / assetWidth);
245
+ } else {
246
+ resolvedHeightValue = assetHeight;
247
+ }
248
+ resolvedHeightUnit = Unit.Pixel;
249
+ }
250
+ super.height(resolvedHeightValue, resolvedHeightUnit);
251
+ }
252
+ }
253
+
254
+ private attachAssetStateListener(): void {
255
+ if (this.trackedTextureAssetId == this.textureIdValue) {
256
+ return;
257
+ }
258
+ this.detachAssetStateListener();
259
+ this.trackedTextureAssetId = this.textureIdValue;
260
+ if (this.textureIdValue == 0) {
261
+ return;
262
+ }
263
+ this.assetStateAction = getTextureAssetState(this.textureIdValue).addAction(
264
+ new HandlerAction<Image, AssetLoadState>(this, (image: Image, _state: AssetLoadState): void => {
265
+ image.applyResolvedSizing();
266
+ }),
267
+ );
268
+ }
269
+
270
+ private detachAssetStateListener(): void {
271
+ if (this.assetStateAction !== null) {
272
+ changetype<Action<AssetLoadState>>(this.assetStateAction).dispose();
273
+ this.assetStateAction = null;
274
+ }
275
+ this.trackedTextureAssetId = 0;
276
+ }
277
+
182
278
  private releaseOwnedSourceAsset(): void {
183
279
  if (this.ownedTextureAssetId == 0) {
184
280
  return;
@@ -39,10 +39,26 @@ export class ScrollView extends Node {
39
39
  private widthUnit: Unit = Unit.Pixel;
40
40
  private hasWidth: bool = false;
41
41
  private hasFillWidth: bool = false;
42
+ private fillWidthPercentValue: f32 = 0.0;
43
+ private hasFillWidthPercent: bool = false;
42
44
  private heightValue: f32 = 0.0;
43
45
  private heightUnit: Unit = Unit.Pixel;
44
46
  private hasHeight: bool = false;
45
47
  private hasFillHeight: bool = false;
48
+ private fillHeightPercentValue: f32 = 0.0;
49
+ private hasFillHeightPercent: bool = false;
50
+ private minWidthValue: f32 = 0.0;
51
+ private minWidthUnit: Unit = Unit.Auto;
52
+ private hasMinWidth: bool = false;
53
+ private maxWidthValue: f32 = 0.0;
54
+ private maxWidthUnit: Unit = Unit.Auto;
55
+ private hasMaxWidth: bool = false;
56
+ private minHeightValue: f32 = 0.0;
57
+ private minHeightUnit: Unit = Unit.Auto;
58
+ private hasMinHeight: bool = false;
59
+ private maxHeightValue: f32 = 0.0;
60
+ private maxHeightUnit: Unit = Unit.Auto;
61
+ private hasMaxHeight: bool = false;
46
62
  private flexBasisValue: f32 = 0.0;
47
63
  private hasFlexBasis: bool = false;
48
64
  private enableScrollX: bool = true;
@@ -100,6 +116,7 @@ export class ScrollView extends Node {
100
116
  this.widthUnit = unit;
101
117
  this.hasWidth = true;
102
118
  this.hasFillWidth = false;
119
+ this.hasFillWidthPercent = false;
103
120
  if (unit == Unit.Pixel) {
104
121
  this._scrollState.viewportWidth.value = value;
105
122
  }
@@ -115,6 +132,7 @@ export class ScrollView extends Node {
115
132
  this.heightUnit = unit;
116
133
  this.hasHeight = true;
117
134
  this.hasFillHeight = false;
135
+ this.hasFillHeightPercent = false;
118
136
  if (unit == Unit.Pixel) {
119
137
  this._scrollState.viewportHeight.value = value;
120
138
  }
@@ -126,7 +144,9 @@ export class ScrollView extends Node {
126
144
  }
127
145
 
128
146
  fillWidth(): this {
147
+ this.hasWidth = false;
129
148
  this.hasFillWidth = true;
149
+ this.hasFillWidthPercent = false;
130
150
  if (this.hasBuiltHandle()) {
131
151
  ui.setFillWidth(this.handle, true);
132
152
  this.notifyRetainedLayoutMutation();
@@ -135,7 +155,9 @@ export class ScrollView extends Node {
135
155
  }
136
156
 
137
157
  fillHeight(): this {
158
+ this.hasHeight = false;
138
159
  this.hasFillHeight = true;
160
+ this.hasFillHeightPercent = false;
139
161
  if (this.hasBuiltHandle()) {
140
162
  ui.setFillHeight(this.handle, true);
141
163
  this.notifyRetainedLayoutMutation();
@@ -149,6 +171,74 @@ export class ScrollView extends Node {
149
171
  return this;
150
172
  }
151
173
 
174
+ fillWidthPercent(percent: f32): this {
175
+ this.hasWidth = false;
176
+ this.hasFillWidth = false;
177
+ this.hasFillWidthPercent = true;
178
+ this.fillWidthPercentValue = percent;
179
+ if (this.hasBuiltHandle()) {
180
+ ui.setFillWidthPercent(this.handle, percent);
181
+ this.notifyRetainedLayoutMutation();
182
+ }
183
+ return this;
184
+ }
185
+
186
+ fillHeightPercent(percent: f32): this {
187
+ this.hasHeight = false;
188
+ this.hasFillHeight = false;
189
+ this.hasFillHeightPercent = true;
190
+ this.fillHeightPercentValue = percent;
191
+ if (this.hasBuiltHandle()) {
192
+ ui.setFillHeightPercent(this.handle, percent);
193
+ this.notifyRetainedLayoutMutation();
194
+ }
195
+ return this;
196
+ }
197
+
198
+ minWidth(value: f32, unit: Unit = Unit.Pixel): this {
199
+ this.minWidthValue = value;
200
+ this.minWidthUnit = unit;
201
+ this.hasMinWidth = unit != Unit.Auto;
202
+ if (this.hasBuiltHandle()) {
203
+ ui.setMinWidth(this.handle, value, <u32>unit);
204
+ this.notifyRetainedLayoutMutation();
205
+ }
206
+ return this;
207
+ }
208
+
209
+ maxWidth(value: f32, unit: Unit = Unit.Pixel): this {
210
+ this.maxWidthValue = value;
211
+ this.maxWidthUnit = unit;
212
+ this.hasMaxWidth = unit != Unit.Auto;
213
+ if (this.hasBuiltHandle()) {
214
+ ui.setMaxWidth(this.handle, value, <u32>unit);
215
+ this.notifyRetainedLayoutMutation();
216
+ }
217
+ return this;
218
+ }
219
+
220
+ minHeight(value: f32, unit: Unit = Unit.Pixel): this {
221
+ this.minHeightValue = value;
222
+ this.minHeightUnit = unit;
223
+ this.hasMinHeight = unit != Unit.Auto;
224
+ if (this.hasBuiltHandle()) {
225
+ ui.setMinHeight(this.handle, value, <u32>unit);
226
+ this.notifyRetainedLayoutMutation();
227
+ }
228
+ return this;
229
+ }
230
+
231
+ maxHeight(value: f32, unit: Unit = Unit.Pixel): this {
232
+ this.maxHeightValue = value;
233
+ this.maxHeightUnit = unit;
234
+ this.hasMaxHeight = unit != Unit.Auto;
235
+ if (this.hasBuiltHandle()) {
236
+ ui.setMaxHeight(this.handle, value, <u32>unit);
237
+ this.notifyRetainedLayoutMutation();
238
+ }
239
+ return this;
240
+ }
241
+
152
242
  flexBasis(value: f32): this {
153
243
  this.flexBasisValue = value;
154
244
  this.hasFlexBasis = true;
@@ -317,12 +407,30 @@ export class ScrollView extends Node {
317
407
  if (this.hasFillWidth) {
318
408
  ui.setFillWidth(this.handle, true);
319
409
  }
410
+ if (this.hasFillWidthPercent) {
411
+ ui.setFillWidthPercent(this.handle, this.fillWidthPercentValue);
412
+ }
320
413
  if (this.hasHeight) {
321
414
  ui.setHeight(this.handle, this.heightValue, <u32>this.heightUnit);
322
415
  }
323
416
  if (this.hasFillHeight) {
324
417
  ui.setFillHeight(this.handle, true);
325
418
  }
419
+ if (this.hasFillHeightPercent) {
420
+ ui.setFillHeightPercent(this.handle, this.fillHeightPercentValue);
421
+ }
422
+ if (this.hasMinWidth) {
423
+ ui.setMinWidth(this.handle, this.minWidthValue, <u32>this.minWidthUnit);
424
+ }
425
+ if (this.hasMaxWidth) {
426
+ ui.setMaxWidth(this.handle, this.maxWidthValue, <u32>this.maxWidthUnit);
427
+ }
428
+ if (this.hasMinHeight) {
429
+ ui.setMinHeight(this.handle, this.minHeightValue, <u32>this.minHeightUnit);
430
+ }
431
+ if (this.hasMaxHeight) {
432
+ ui.setMaxHeight(this.handle, this.maxHeightValue, <u32>this.maxHeightUnit);
433
+ }
326
434
  if (this.hasFlexBasis) {
327
435
  ui.setFlexBasis(this.handle, this.flexBasisValue);
328
436
  }
package/src/nodes/Text.ts CHANGED
@@ -18,12 +18,30 @@ export class Text extends TextCore {
18
18
  if (props.hasFillWidth) {
19
19
  text.fillWidth();
20
20
  }
21
+ if (props.hasFillWidthPercent) {
22
+ text.fillWidthPercent(props.fillWidthPercentValue);
23
+ }
21
24
  if (props.hasHeight) {
22
25
  text.height(props.heightValue, props.heightUnit);
23
26
  }
24
27
  if (props.hasFillHeight) {
25
28
  text.fillHeight();
26
29
  }
30
+ if (props.hasFillHeightPercent) {
31
+ text.fillHeightPercent(props.fillHeightPercentValue);
32
+ }
33
+ if (props.hasMinWidth) {
34
+ text.minWidth(props.minWidthValue, props.minWidthUnit);
35
+ }
36
+ if (props.hasMaxWidth) {
37
+ text.maxWidth(props.maxWidthValue, props.maxWidthUnit);
38
+ }
39
+ if (props.hasMinHeight) {
40
+ text.minHeight(props.minHeightValue, props.minHeightUnit);
41
+ }
42
+ if (props.hasMaxHeight) {
43
+ text.maxHeight(props.maxHeightValue, props.maxHeightUnit);
44
+ }
27
45
  if (props.hasFontFamily) {
28
46
  const family = props.fontFamilyValue;
29
47
  if (family !== null) {
@@ -21,10 +21,26 @@ export class TextProps {
21
21
  widthUnit: Unit = Unit.Pixel;
22
22
  hasWidth: bool = false;
23
23
  hasFillWidth: bool = false;
24
+ fillWidthPercentValue: f32 = 0.0;
25
+ hasFillWidthPercent: bool = false;
24
26
  heightValue: f32 = 0.0;
25
27
  heightUnit: Unit = Unit.Pixel;
26
28
  hasHeight: bool = false;
27
29
  hasFillHeight: bool = false;
30
+ fillHeightPercentValue: f32 = 0.0;
31
+ hasFillHeightPercent: bool = false;
32
+ minWidthValue: f32 = 0.0;
33
+ minWidthUnit: Unit = Unit.Auto;
34
+ hasMinWidth: bool = false;
35
+ maxWidthValue: f32 = 0.0;
36
+ maxWidthUnit: Unit = Unit.Auto;
37
+ hasMaxWidth: bool = false;
38
+ minHeightValue: f32 = 0.0;
39
+ minHeightUnit: Unit = Unit.Auto;
40
+ hasMinHeight: bool = false;
41
+ maxHeightValue: f32 = 0.0;
42
+ maxHeightUnit: Unit = Unit.Auto;
43
+ hasMaxHeight: bool = false;
28
44
  fontId: u32 = 0;
29
45
  fontSize: f32 = 0.0;
30
46
  hasFont: bool = false;
@@ -69,10 +85,26 @@ export class TextCore extends Node {
69
85
  private widthUnit: Unit = Unit.Pixel;
70
86
  private hasWidth: bool = false;
71
87
  private hasFillWidth: bool = false;
88
+ private fillWidthPercentValue: f32 = 0.0;
89
+ private hasFillWidthPercent: bool = false;
72
90
  private heightValue: f32 = 0.0;
73
91
  private heightUnit: Unit = Unit.Pixel;
74
92
  private hasHeight: bool = false;
75
93
  private hasFillHeight: bool = false;
94
+ private fillHeightPercentValue: f32 = 0.0;
95
+ private hasFillHeightPercent: bool = false;
96
+ private minWidthValue: f32 = 0.0;
97
+ private minWidthUnit: Unit = Unit.Auto;
98
+ private hasMinWidth: bool = false;
99
+ private maxWidthValue: f32 = 0.0;
100
+ private maxWidthUnit: Unit = Unit.Auto;
101
+ private hasMaxWidth: bool = false;
102
+ private minHeightValue: f32 = 0.0;
103
+ private minHeightUnit: Unit = Unit.Auto;
104
+ private hasMinHeight: bool = false;
105
+ private maxHeightValue: f32 = 0.0;
106
+ private maxHeightUnit: Unit = Unit.Auto;
107
+ private hasMaxHeight: bool = false;
76
108
  private fontId: u32 = 0;
77
109
  private fontSizeValue: f32 = 0.0;
78
110
  private hasFont: bool = false;
@@ -152,6 +184,7 @@ export class TextCore extends Node {
152
184
  this.widthUnit = unit;
153
185
  this.hasWidth = true;
154
186
  this.hasFillWidth = false;
187
+ this.hasFillWidthPercent = false;
155
188
  if (this.hasBuiltHandle()) {
156
189
  ui.setWidth(this.handle, value, <u32>unit);
157
190
  this.notifyRetainedLayoutMutation();
@@ -164,6 +197,7 @@ export class TextCore extends Node {
164
197
  this.heightUnit = unit;
165
198
  this.hasHeight = true;
166
199
  this.hasFillHeight = false;
200
+ this.hasFillHeightPercent = false;
167
201
  if (this.hasBuiltHandle()) {
168
202
  ui.setHeight(this.handle, value, <u32>unit);
169
203
  this.notifyRetainedLayoutMutation();
@@ -172,7 +206,9 @@ export class TextCore extends Node {
172
206
  }
173
207
 
174
208
  fillWidth(): this {
209
+ this.hasWidth = false;
175
210
  this.hasFillWidth = true;
211
+ this.hasFillWidthPercent = false;
176
212
  if (this.hasBuiltHandle()) {
177
213
  ui.setFillWidth(this.handle, true);
178
214
  this.notifyRetainedLayoutMutation();
@@ -181,7 +217,9 @@ export class TextCore extends Node {
181
217
  }
182
218
 
183
219
  fillHeight(): this {
220
+ this.hasHeight = false;
184
221
  this.hasFillHeight = true;
222
+ this.hasFillHeightPercent = false;
185
223
  if (this.hasBuiltHandle()) {
186
224
  ui.setFillHeight(this.handle, true);
187
225
  this.notifyRetainedLayoutMutation();
@@ -189,6 +227,74 @@ export class TextCore extends Node {
189
227
  return this;
190
228
  }
191
229
 
230
+ fillWidthPercent(percent: f32): this {
231
+ this.hasWidth = false;
232
+ this.hasFillWidth = false;
233
+ this.hasFillWidthPercent = true;
234
+ this.fillWidthPercentValue = percent;
235
+ if (this.hasBuiltHandle()) {
236
+ ui.setFillWidthPercent(this.handle, percent);
237
+ this.notifyRetainedLayoutMutation();
238
+ }
239
+ return this;
240
+ }
241
+
242
+ fillHeightPercent(percent: f32): this {
243
+ this.hasHeight = false;
244
+ this.hasFillHeight = false;
245
+ this.hasFillHeightPercent = true;
246
+ this.fillHeightPercentValue = percent;
247
+ if (this.hasBuiltHandle()) {
248
+ ui.setFillHeightPercent(this.handle, percent);
249
+ this.notifyRetainedLayoutMutation();
250
+ }
251
+ return this;
252
+ }
253
+
254
+ minWidth(value: f32, unit: Unit = Unit.Pixel): this {
255
+ this.minWidthValue = value;
256
+ this.minWidthUnit = unit;
257
+ this.hasMinWidth = unit != Unit.Auto;
258
+ if (this.hasBuiltHandle()) {
259
+ ui.setMinWidth(this.handle, value, <u32>unit);
260
+ this.notifyRetainedLayoutMutation();
261
+ }
262
+ return this;
263
+ }
264
+
265
+ maxWidth(value: f32, unit: Unit = Unit.Pixel): this {
266
+ this.maxWidthValue = value;
267
+ this.maxWidthUnit = unit;
268
+ this.hasMaxWidth = unit != Unit.Auto;
269
+ if (this.hasBuiltHandle()) {
270
+ ui.setMaxWidth(this.handle, value, <u32>unit);
271
+ this.notifyRetainedLayoutMutation();
272
+ }
273
+ return this;
274
+ }
275
+
276
+ minHeight(value: f32, unit: Unit = Unit.Pixel): this {
277
+ this.minHeightValue = value;
278
+ this.minHeightUnit = unit;
279
+ this.hasMinHeight = unit != Unit.Auto;
280
+ if (this.hasBuiltHandle()) {
281
+ ui.setMinHeight(this.handle, value, <u32>unit);
282
+ this.notifyRetainedLayoutMutation();
283
+ }
284
+ return this;
285
+ }
286
+
287
+ maxHeight(value: f32, unit: Unit = Unit.Pixel): this {
288
+ this.maxHeightValue = value;
289
+ this.maxHeightUnit = unit;
290
+ this.hasMaxHeight = unit != Unit.Auto;
291
+ if (this.hasBuiltHandle()) {
292
+ ui.setMaxHeight(this.handle, value, <u32>unit);
293
+ this.notifyRetainedLayoutMutation();
294
+ }
295
+ return this;
296
+ }
297
+
192
298
  fillSize(): this {
193
299
  this.fillWidth();
194
300
  this.fillHeight();
@@ -456,12 +562,30 @@ export class TextCore extends Node {
456
562
  if (this.hasFillWidth) {
457
563
  ui.setFillWidth(this.handle, true);
458
564
  }
565
+ if (this.hasFillWidthPercent) {
566
+ ui.setFillWidthPercent(this.handle, this.fillWidthPercentValue);
567
+ }
459
568
  if (this.hasHeight) {
460
569
  ui.setHeight(this.handle, this.heightValue, <u32>this.heightUnit);
461
570
  }
462
571
  if (this.hasFillHeight) {
463
572
  ui.setFillHeight(this.handle, true);
464
573
  }
574
+ if (this.hasFillHeightPercent) {
575
+ ui.setFillHeightPercent(this.handle, this.fillHeightPercentValue);
576
+ }
577
+ if (this.hasMinWidth) {
578
+ ui.setMinWidth(this.handle, this.minWidthValue, <u32>this.minWidthUnit);
579
+ }
580
+ if (this.hasMaxWidth) {
581
+ ui.setMaxWidth(this.handle, this.maxWidthValue, <u32>this.maxWidthUnit);
582
+ }
583
+ if (this.hasMinHeight) {
584
+ ui.setMinHeight(this.handle, this.minHeightValue, <u32>this.minHeightUnit);
585
+ }
586
+ if (this.hasMaxHeight) {
587
+ ui.setMaxHeight(this.handle, this.maxHeightValue, <u32>this.maxHeightUnit);
588
+ }
465
589
  ui.setText(this.handle, this.contentValue);
466
590
  if (this.textStyleRunsWords !== null) {
467
591
  ui.setTextStyleRuns(this.handle, changetype<Uint32Array>(this.textStyleRunsWords));