@effindomv2/fui-as 0.1.15 → 0.1.16

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effindomv2/fui-as",
3
- "version": "0.1.15",
3
+ "version": "0.1.16",
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",
@@ -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
 
@@ -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;