@effindomv2/fui-as 0.1.11 → 0.1.13

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.11",
3
+ "version": "0.1.13",
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.4"
81
+ "@effindomv2/runtime": "0.1.5"
82
82
  },
83
83
  "devDependencies": {
84
84
  "@as-pect/assembly": "8.1.0",
package/src/Fui.ts CHANGED
@@ -148,10 +148,12 @@ export {
148
148
  ControlTemplateSet,
149
149
  ContextMenu,
150
150
  Dialog,
151
+ DropdownSizing,
151
152
  DropdownChevronPresenter,
152
153
  DropdownChevronTemplate,
153
154
  DropdownChevronVisualState,
154
155
  Dropdown,
156
+ DropdownFieldMetrics,
155
157
  DropdownFieldPresenter,
156
158
  DropdownFieldTemplate,
157
159
  DropdownFieldVisualState,
@@ -164,6 +166,7 @@ export {
164
166
  getControlTemplates,
165
167
  MenuItem,
166
168
  NavLink,
169
+ LabeledControlSizing,
167
170
  PressableIndicatorMetrics,
168
171
  ProgressBar,
169
172
  RadioIndicatorPresenter,
@@ -173,6 +176,7 @@ export {
173
176
  RadioGroup,
174
177
  SelectionArea,
175
178
  Slider,
179
+ SliderSizing,
176
180
  SliderPresenter,
177
181
  SliderPresenterMetrics,
178
182
  SliderTemplate,
@@ -2,6 +2,7 @@ import { Callback1, Handler1 } from "../core/BoundCallback";
2
2
  import { SemanticCheckedState, SemanticRole } from "../core/ffi";
3
3
  import { PersistedInt32Codec, PersistedValueState } from "../core/PersistedState";
4
4
  import { bind1 } from "../core/bind";
5
+ import { LabeledControlSizing } from "./ControlSizing";
5
6
  import { getControlTemplates } from "./ControlTemplateSet";
6
7
  import { activeTheme } from "../core/Theme";
7
8
  import { PressableLabeledControl } from "./internal/PressableLabeledControl";
@@ -9,7 +10,7 @@ import {
9
10
  CheckboxIndicatorPresenter,
10
11
  CheckboxIndicatorTemplate,
11
12
  CheckboxIndicatorVisualState,
12
- defaultCheckboxIndicatorTemplate,
13
+ createDefaultCheckboxIndicatorPresenter,
13
14
  } from "./internal/CheckboxIndicatorPresenter";
14
15
  const CHECKBOX_PERSISTED_CODEC = new PersistedInt32Codec();
15
16
 
@@ -39,18 +40,21 @@ class PersistedCheckboxState extends PersistedValueState<Checkbox, i32> {
39
40
 
40
41
  const CHECKBOX_PERSISTED_STATE = new PersistedCheckboxState();
41
42
 
42
- function createIndicatorPresenter(template: CheckboxIndicatorTemplate | null): CheckboxIndicatorPresenter {
43
+ function createIndicatorPresenter(template: CheckboxIndicatorTemplate | null, sizing: LabeledControlSizing | null = null): CheckboxIndicatorPresenter {
43
44
  if (template !== null) {
44
45
  return template.create();
45
46
  }
46
47
  const templateSet = getControlTemplates();
47
48
  const appTemplate = templateSet !== null ? templateSet.checkboxIndicator : null;
48
- return (appTemplate === null ? defaultCheckboxIndicatorTemplate : appTemplate).create();
49
+ return appTemplate === null
50
+ ? createDefaultCheckboxIndicatorPresenter(sizing)
51
+ : appTemplate.create();
49
52
  }
50
53
 
51
54
  export class Checkbox extends PressableLabeledControl {
52
55
  private indicatorPresenter: CheckboxIndicatorPresenter;
53
56
  private templateOverride: CheckboxIndicatorTemplate | null = null;
57
+ private sizingValue: LabeledControlSizing | null = null;
54
58
  private checkedStateValue: SemanticCheckedState = SemanticCheckedState.False;
55
59
  private triStateEnabled: bool = false;
56
60
  private changedCallback: ((state: SemanticCheckedState) => void) | null = null;
@@ -94,9 +98,22 @@ export class Checkbox extends PressableLabeledControl {
94
98
  return this;
95
99
  }
96
100
 
101
+ sizing(sizing: LabeledControlSizing | null): this {
102
+ this.sizingValue = sizing;
103
+ this.setLabelFontSizeOverride(
104
+ sizing !== null && sizing.hasLabelFontSize ? sizing.labelFontSizePx : 0.0,
105
+ );
106
+ if (this.usesDefaultIndicatorPresenter()) {
107
+ this.indicatorPresenter = createIndicatorPresenter(this.templateOverride, this.sizingValue);
108
+ this.replaceIndicatorRoot(this.indicatorPresenter.root);
109
+ this.syncVisualState();
110
+ }
111
+ return this;
112
+ }
113
+
97
114
  template(template: CheckboxIndicatorTemplate | null): this {
98
115
  this.templateOverride = template;
99
- this.indicatorPresenter = createIndicatorPresenter(this.templateOverride);
116
+ this.indicatorPresenter = createIndicatorPresenter(this.templateOverride, this.sizingValue);
100
117
  this.replaceIndicatorRoot(this.indicatorPresenter.root);
101
118
  this.syncVisualState();
102
119
  return this;
@@ -178,4 +195,12 @@ export class Checkbox extends PressableLabeledControl {
178
195
  }
179
196
  }
180
197
 
198
+ private usesDefaultIndicatorPresenter(): bool {
199
+ if (this.templateOverride !== null) {
200
+ return false;
201
+ }
202
+ const templateSet = getControlTemplates();
203
+ return templateSet === null || templateSet.checkboxIndicator === null;
204
+ }
205
+
181
206
  }
@@ -0,0 +1,158 @@
1
+ import { warn } from "../core/Logger";
2
+
3
+ function sanitizePositive(owner: string, property: string, value: f32): f32 {
4
+ if (value <= 0.0) {
5
+ warn("Layout", owner + "." + property + "() received " + value.toString() + "; ignoring.");
6
+ return 0.0;
7
+ }
8
+ return value;
9
+ }
10
+
11
+ export class LabeledControlSizing {
12
+ private indicatorSizeValue: f32 = 0.0;
13
+ private labelFontSizeValue: f32 = 0.0;
14
+
15
+ indicatorSize(value: f32): this {
16
+ this.indicatorSizeValue = sanitizePositive("LabeledControlSizing", "indicatorSize", value);
17
+ return this;
18
+ }
19
+
20
+ labelFontSize(value: f32): this {
21
+ this.labelFontSizeValue = sanitizePositive("LabeledControlSizing", "labelFontSize", value);
22
+ return this;
23
+ }
24
+
25
+ get hasIndicatorSize(): bool {
26
+ return this.indicatorSizeValue > 0.0;
27
+ }
28
+
29
+ get hasLabelFontSize(): bool {
30
+ return this.labelFontSizeValue > 0.0;
31
+ }
32
+
33
+ get indicatorSizePx(): f32 {
34
+ return this.indicatorSizeValue;
35
+ }
36
+
37
+ get labelFontSizePx(): f32 {
38
+ return this.labelFontSizeValue;
39
+ }
40
+ }
41
+
42
+ export class SliderSizing {
43
+ private thumbSizeValue: f32 = 0.0;
44
+ private trackThicknessValue: f32 = 0.0;
45
+
46
+ thumbSize(value: f32): this {
47
+ this.thumbSizeValue = sanitizePositive("SliderSizing", "thumbSize", value);
48
+ return this;
49
+ }
50
+
51
+ trackThickness(value: f32): this {
52
+ this.trackThicknessValue = sanitizePositive("SliderSizing", "trackThickness", value);
53
+ return this;
54
+ }
55
+
56
+ get hasThumbSize(): bool {
57
+ return this.thumbSizeValue > 0.0;
58
+ }
59
+
60
+ get hasTrackThickness(): bool {
61
+ return this.trackThicknessValue > 0.0;
62
+ }
63
+
64
+ get thumbSizePx(): f32 {
65
+ return this.thumbSizeValue;
66
+ }
67
+
68
+ get trackThicknessPx(): f32 {
69
+ return this.trackThicknessValue;
70
+ }
71
+ }
72
+
73
+ export class DropdownSizing {
74
+ private fieldFontSizeValue: f32 = 0.0;
75
+ private optionFontSizeValue: f32 = 0.0;
76
+ private fieldHeightValue: f32 = 0.0;
77
+ private optionHeightValue: f32 = 0.0;
78
+ private chevronBoxSizeValue: f32 = 0.0;
79
+ private chevronIconSizeValue: f32 = 0.0;
80
+
81
+ fieldFontSize(value: f32): this {
82
+ this.fieldFontSizeValue = sanitizePositive("DropdownSizing", "fieldFontSize", value);
83
+ return this;
84
+ }
85
+
86
+ optionFontSize(value: f32): this {
87
+ this.optionFontSizeValue = sanitizePositive("DropdownSizing", "optionFontSize", value);
88
+ return this;
89
+ }
90
+
91
+ fieldHeight(value: f32): this {
92
+ this.fieldHeightValue = sanitizePositive("DropdownSizing", "fieldHeight", value);
93
+ return this;
94
+ }
95
+
96
+ optionHeight(value: f32): this {
97
+ this.optionHeightValue = sanitizePositive("DropdownSizing", "optionHeight", value);
98
+ return this;
99
+ }
100
+
101
+ chevronBoxSize(value: f32): this {
102
+ this.chevronBoxSizeValue = sanitizePositive("DropdownSizing", "chevronBoxSize", value);
103
+ return this;
104
+ }
105
+
106
+ chevronIconSize(value: f32): this {
107
+ this.chevronIconSizeValue = sanitizePositive("DropdownSizing", "chevronIconSize", value);
108
+ return this;
109
+ }
110
+
111
+ get hasFieldFontSize(): bool {
112
+ return this.fieldFontSizeValue > 0.0;
113
+ }
114
+
115
+ get hasOptionFontSize(): bool {
116
+ return this.optionFontSizeValue > 0.0;
117
+ }
118
+
119
+ get hasFieldHeight(): bool {
120
+ return this.fieldHeightValue > 0.0;
121
+ }
122
+
123
+ get hasOptionHeight(): bool {
124
+ return this.optionHeightValue > 0.0;
125
+ }
126
+
127
+ get hasChevronBoxSize(): bool {
128
+ return this.chevronBoxSizeValue > 0.0;
129
+ }
130
+
131
+ get hasChevronIconSize(): bool {
132
+ return this.chevronIconSizeValue > 0.0;
133
+ }
134
+
135
+ get fieldFontSizePx(): f32 {
136
+ return this.fieldFontSizeValue;
137
+ }
138
+
139
+ get optionFontSizePx(): f32 {
140
+ return this.optionFontSizeValue;
141
+ }
142
+
143
+ get fieldHeightPx(): f32 {
144
+ return this.fieldHeightValue;
145
+ }
146
+
147
+ get optionHeightPx(): f32 {
148
+ return this.optionHeightValue;
149
+ }
150
+
151
+ get chevronBoxSizePx(): f32 {
152
+ return this.chevronBoxSizeValue;
153
+ }
154
+
155
+ get chevronIconSizePx(): f32 {
156
+ return this.chevronIconSizeValue;
157
+ }
158
+ }
@@ -22,21 +22,22 @@ import { PersistedInt32Codec, PersistedValueState } from "../core/PersistedState
22
22
  import { registerScrollHook } from "../core/ScrollHooks";
23
23
  import { FlexBox, Portal, ScrollBarVisibility, ScrollBox, ScrollView } from "../nodes";
24
24
  import { bind2 } from "../core/bind";
25
+ import { DropdownSizing } from "./ControlSizing";
25
26
  import { getControlTemplates } from "./ControlTemplateSet";
26
27
  import {
27
- defaultDropdownChevronTemplate,
28
+ createDefaultDropdownChevronPresenter,
28
29
  DropdownChevronPresenter,
29
30
  DropdownChevronTemplate,
30
31
  DropdownChevronVisualState,
31
32
  } from "./internal/DropdownChevronPresenter";
32
33
  import {
33
- defaultDropdownFieldTemplate,
34
+ createDefaultDropdownFieldPresenter,
34
35
  DropdownFieldPresenter,
35
36
  DropdownFieldTemplate,
36
37
  DropdownFieldVisualState,
37
38
  } from "./internal/DropdownFieldPresenter";
38
39
  import {
39
- defaultDropdownOptionRowTemplate,
40
+ createDefaultDropdownOptionRowPresenter,
40
41
  DropdownOptionRowPresenter,
41
42
  DropdownOptionRowTemplate,
42
43
  DropdownOptionRowVisualState,
@@ -74,31 +75,37 @@ class PersistedDropdownState extends PersistedValueState<Dropdown, i32> {
74
75
 
75
76
  const DROPDOWN_PERSISTED_STATE = new PersistedDropdownState();
76
77
 
77
- function createFieldPresenter(template: DropdownFieldTemplate | null): DropdownFieldPresenter {
78
+ function createFieldPresenter(template: DropdownFieldTemplate | null, sizing: DropdownSizing | null = null): DropdownFieldPresenter {
78
79
  if (template !== null) {
79
80
  return template.create();
80
81
  }
81
82
  const templateSet = getControlTemplates();
82
83
  const appTemplate = templateSet !== null ? templateSet.dropdownField : null;
83
- return (appTemplate === null ? defaultDropdownFieldTemplate : appTemplate).create();
84
+ return appTemplate === null
85
+ ? createDefaultDropdownFieldPresenter(sizing)
86
+ : appTemplate.create();
84
87
  }
85
88
 
86
- function createChevronPresenter(template: DropdownChevronTemplate | null): DropdownChevronPresenter {
89
+ function createChevronPresenter(template: DropdownChevronTemplate | null, sizing: DropdownSizing | null = null): DropdownChevronPresenter {
87
90
  if (template !== null) {
88
91
  return template.create();
89
92
  }
90
93
  const templateSet = getControlTemplates();
91
94
  const appTemplate = templateSet !== null ? templateSet.dropdownChevron : null;
92
- return (appTemplate === null ? defaultDropdownChevronTemplate : appTemplate).create();
95
+ return appTemplate === null
96
+ ? createDefaultDropdownChevronPresenter(sizing)
97
+ : appTemplate.create();
93
98
  }
94
99
 
95
- function createOptionRowPresenter(template: DropdownOptionRowTemplate | null): DropdownOptionRowPresenter {
100
+ function createOptionRowPresenter(template: DropdownOptionRowTemplate | null, sizing: DropdownSizing | null = null): DropdownOptionRowPresenter {
96
101
  if (template !== null) {
97
102
  return template.create();
98
103
  }
99
104
  const templateSet = getControlTemplates();
100
105
  const appTemplate = templateSet !== null ? templateSet.dropdownOptionRow : null;
101
- return (appTemplate === null ? defaultDropdownOptionRowTemplate : appTemplate).create();
106
+ return appTemplate === null
107
+ ? createDefaultDropdownOptionRowPresenter(sizing)
108
+ : appTemplate.create();
102
109
  }
103
110
 
104
111
  export class DropdownItem {
@@ -111,9 +118,9 @@ class DropdownOptionNode extends FlexBox {
111
118
  private slotIndex: i32 = -1;
112
119
  private currentLabel: string = "";
113
120
 
114
- constructor(template: DropdownOptionRowTemplate | null) {
121
+ constructor(template: DropdownOptionRowTemplate | null, sizing: DropdownSizing | null) {
115
122
  super();
116
- this.presenter = createOptionRowPresenter(template);
123
+ this.presenter = createOptionRowPresenter(template, sizing);
117
124
  this.semanticRole(SemanticRole.ListItem);
118
125
  this.width(100.0, Unit.Percent);
119
126
  this.cursor(CursorStyle.Pointer);
@@ -136,9 +143,9 @@ class DropdownOptionNode extends FlexBox {
136
143
  return this;
137
144
  }
138
145
 
139
- template(template: DropdownOptionRowTemplate | null): void {
146
+ template(template: DropdownOptionRowTemplate | null, sizing: DropdownSizing | null): void {
140
147
  const previousPresenter = this.presenter;
141
- const nextPresenter = createOptionRowPresenter(template);
148
+ const nextPresenter = createOptionRowPresenter(template, sizing);
142
149
  this.presenter = nextPresenter;
143
150
  this.removeChildNode(previousPresenter.root);
144
151
  this.addChildNode(nextPresenter.root);
@@ -185,6 +192,7 @@ export class Dropdown extends FlexBox implements GlobalKeyHandler {
185
192
  private fieldTemplateValue: DropdownFieldTemplate | null = null;
186
193
  private chevronTemplateValue: DropdownChevronTemplate | null = null;
187
194
  private optionRowTemplateValue: DropdownOptionRowTemplate | null = null;
195
+ private sizingValue: DropdownSizing | null = null;
188
196
  private fieldPresenter: DropdownFieldPresenter;
189
197
  private chevronPresenter: DropdownChevronPresenter;
190
198
  private readonly popupRoot: Portal;
@@ -215,8 +223,8 @@ export class Dropdown extends FlexBox implements GlobalKeyHandler {
215
223
  constructor() {
216
224
  super();
217
225
  Dropdown.ensureScrollHook();
218
- const fieldPresenter = createFieldPresenter(null);
219
- const chevronPresenter = createChevronPresenter(null);
226
+ const fieldPresenter = createFieldPresenter(null, null);
227
+ const chevronPresenter = createChevronPresenter(null, null);
220
228
  const popupRoot = new Portal()
221
229
  .positionAbsolute()
222
230
  .position(0.0, 0.0)
@@ -340,11 +348,38 @@ export class Dropdown extends FlexBox implements GlobalKeyHandler {
340
348
  return this;
341
349
  }
342
350
 
351
+ sizing(sizing: DropdownSizing | null): this {
352
+ this.close();
353
+ this.sizingValue = sizing;
354
+ if (this.usesDefaultFieldPresenter()) {
355
+ this.replaceFieldPresenter(
356
+ createFieldPresenter(this.fieldTemplateValue, this.sizingValue),
357
+ createChevronPresenter(this.chevronTemplateValue, this.sizingValue),
358
+ );
359
+ } else if (this.usesDefaultChevronPresenter()) {
360
+ const previousPresenter = this.chevronPresenter;
361
+ const nextPresenter = createChevronPresenter(this.chevronTemplateValue, this.sizingValue);
362
+ this.chevronPresenter = nextPresenter;
363
+ this.fieldPresenter.chevronHost.removeChildNode(previousPresenter.root);
364
+ this.fieldPresenter.chevronHost.addChildNode(nextPresenter.root);
365
+ previousPresenter.root.dispose();
366
+ }
367
+ if (this.usesDefaultOptionRowPresenter()) {
368
+ for (let index = 0; index < this.optionNodes.length; ++index) {
369
+ unchecked(this.optionNodes[index]).template(this.optionRowTemplateValue, this.sizingValue);
370
+ }
371
+ this.refreshPanelLayout();
372
+ }
373
+ this.syncValueLabel();
374
+ this.handleThemeChanged();
375
+ return this;
376
+ }
377
+
343
378
  fieldTemplate(template: DropdownFieldTemplate | null): this {
344
379
  this.close();
345
380
  this.fieldTemplateValue = template;
346
- const nextFieldPresenter = createFieldPresenter(template);
347
- const nextChevronPresenter = createChevronPresenter(this.chevronTemplateValue);
381
+ const nextFieldPresenter = createFieldPresenter(template, this.sizingValue);
382
+ const nextChevronPresenter = createChevronPresenter(this.chevronTemplateValue, this.sizingValue);
348
383
  this.replaceFieldPresenter(nextFieldPresenter, nextChevronPresenter);
349
384
  this.syncValueLabel();
350
385
  this.handleThemeChanged();
@@ -355,7 +390,7 @@ export class Dropdown extends FlexBox implements GlobalKeyHandler {
355
390
  this.close();
356
391
  this.chevronTemplateValue = template;
357
392
  const previousPresenter = this.chevronPresenter;
358
- const nextPresenter = createChevronPresenter(template);
393
+ const nextPresenter = createChevronPresenter(template, this.sizingValue);
359
394
  this.chevronPresenter = nextPresenter;
360
395
  this.fieldPresenter.chevronHost.removeChildNode(previousPresenter.root);
361
396
  this.fieldPresenter.chevronHost.addChildNode(nextPresenter.root);
@@ -368,7 +403,7 @@ export class Dropdown extends FlexBox implements GlobalKeyHandler {
368
403
  this.close();
369
404
  this.optionRowTemplateValue = template;
370
405
  for (let index = 0; index < this.optionNodes.length; ++index) {
371
- unchecked(this.optionNodes[index]).template(template);
406
+ unchecked(this.optionNodes[index]).template(template, this.sizingValue);
372
407
  }
373
408
  this.refreshPanelLayout();
374
409
  this.syncOptionVisuals();
@@ -763,13 +798,21 @@ export class Dropdown extends FlexBox implements GlobalKeyHandler {
763
798
 
764
799
  private ensureOptionNodes(): void {
765
800
  while (this.optionNodes.length < this.itemsValue.length) {
766
- const optionNode = new DropdownOptionNode(this.optionRowTemplateValue).bindOwner(this, this.optionNodes.length);
801
+ const optionNode = new DropdownOptionNode(this.optionRowTemplateValue, this.sizingValue).bindOwner(this, this.optionNodes.length);
767
802
  this.optionNodes.push(optionNode);
768
803
  }
769
804
  }
770
805
 
771
806
  private resolveOptionRowHeight(): f32 {
772
807
  if (this.optionNodes.length == 0) {
808
+ const sizing = this.sizingValue;
809
+ if (
810
+ sizing !== null &&
811
+ sizing.hasOptionHeight &&
812
+ this.usesDefaultOptionRowPresenter()
813
+ ) {
814
+ return sizing.optionHeightPx;
815
+ }
773
816
  return OPTION_HEIGHT;
774
817
  }
775
818
  return unchecked(this.optionNodes[0]).rowHeight;
@@ -922,4 +965,28 @@ export class Dropdown extends FlexBox implements GlobalKeyHandler {
922
965
  this.replaceChildren(children);
923
966
  previousFieldRoot.dispose();
924
967
  }
968
+
969
+ private usesDefaultFieldPresenter(): bool {
970
+ if (this.fieldTemplateValue !== null) {
971
+ return false;
972
+ }
973
+ const templateSet = getControlTemplates();
974
+ return templateSet === null || templateSet.dropdownField === null;
975
+ }
976
+
977
+ private usesDefaultChevronPresenter(): bool {
978
+ if (this.chevronTemplateValue !== null) {
979
+ return false;
980
+ }
981
+ const templateSet = getControlTemplates();
982
+ return templateSet === null || templateSet.dropdownChevron === null;
983
+ }
984
+
985
+ private usesDefaultOptionRowPresenter(): bool {
986
+ if (this.optionRowTemplateValue !== null) {
987
+ return false;
988
+ }
989
+ const templateSet = getControlTemplates();
990
+ return templateSet === null || templateSet.dropdownOptionRow === null;
991
+ }
925
992
  }
@@ -1,27 +1,31 @@
1
1
  import { KeyEventType, SemanticCheckedState, SemanticRole } from "../core/ffi";
2
2
  import { activeTheme } from "../core/Theme";
3
+ import { LabeledControlSizing } from "./ControlSizing";
3
4
  import { PressableLabeledControl } from "./internal/PressableLabeledControl";
4
5
  import { getControlTemplates } from "./ControlTemplateSet";
5
6
  import { RadioGroup } from "./RadioGroup";
6
7
  import {
7
- defaultRadioIndicatorTemplate,
8
+ createDefaultRadioIndicatorPresenter,
8
9
  RadioIndicatorPresenter,
9
10
  RadioIndicatorTemplate,
10
11
  RadioIndicatorVisualState,
11
12
  } from "./internal/RadioIndicatorPresenter";
12
13
 
13
- function createIndicatorPresenter(template: RadioIndicatorTemplate | null): RadioIndicatorPresenter {
14
+ function createIndicatorPresenter(template: RadioIndicatorTemplate | null, sizing: LabeledControlSizing | null = null): RadioIndicatorPresenter {
14
15
  if (template !== null) {
15
16
  return template.create();
16
17
  }
17
18
  const templateSet = getControlTemplates();
18
19
  const appTemplate = templateSet !== null ? templateSet.radioIndicator : null;
19
- return (appTemplate === null ? defaultRadioIndicatorTemplate : appTemplate).create();
20
+ return appTemplate === null
21
+ ? createDefaultRadioIndicatorPresenter(sizing)
22
+ : appTemplate.create();
20
23
  }
21
24
 
22
25
  export class RadioButton extends PressableLabeledControl {
23
26
  private indicatorPresenter: RadioIndicatorPresenter;
24
27
  private templateOverride: RadioIndicatorTemplate | null = null;
28
+ private sizingValue: LabeledControlSizing | null = null;
25
29
  private readonly valueText: string;
26
30
  private checkedValue: bool = false;
27
31
  private changedCallback: ((checked: bool) => void) | null = null;
@@ -54,9 +58,22 @@ export class RadioButton extends PressableLabeledControl {
54
58
  return this;
55
59
  }
56
60
 
61
+ sizing(sizing: LabeledControlSizing | null): this {
62
+ this.sizingValue = sizing;
63
+ this.setLabelFontSizeOverride(
64
+ sizing !== null && sizing.hasLabelFontSize ? sizing.labelFontSizePx : 0.0,
65
+ );
66
+ if (this.usesDefaultIndicatorPresenter()) {
67
+ this.indicatorPresenter = createIndicatorPresenter(this.templateOverride, this.sizingValue);
68
+ this.replaceIndicatorRoot(this.indicatorPresenter.root);
69
+ this.syncVisualState();
70
+ }
71
+ return this;
72
+ }
73
+
57
74
  template(template: RadioIndicatorTemplate | null): this {
58
75
  this.templateOverride = template;
59
- this.indicatorPresenter = createIndicatorPresenter(this.templateOverride);
76
+ this.indicatorPresenter = createIndicatorPresenter(this.templateOverride, this.sizingValue);
60
77
  this.replaceIndicatorRoot(this.indicatorPresenter.root);
61
78
  this.syncVisualState();
62
79
  return this;
@@ -132,4 +149,12 @@ export class RadioButton extends PressableLabeledControl {
132
149
  }
133
150
  }
134
151
  }
152
+
153
+ private usesDefaultIndicatorPresenter(): bool {
154
+ if (this.templateOverride !== null) {
155
+ return false;
156
+ }
157
+ const templateSet = getControlTemplates();
158
+ return templateSet === null || templateSet.radioIndicator === null;
159
+ }
135
160
  }
@@ -20,9 +20,10 @@ import { PersistedFloat32Codec, PersistedValueState } from "../core/PersistedSta
20
20
  import { Node } from "../core/Node";
21
21
  import { FlexBox } from "../nodes";
22
22
  import { bind1 } from "../core/bind";
23
+ import { SliderSizing } from "./ControlSizing";
23
24
  import { getControlTemplates } from "./ControlTemplateSet";
24
25
  import {
25
- defaultSliderTemplate,
26
+ createDefaultSliderPresenter,
26
27
  SliderPresenter,
27
28
  SliderTemplate,
28
29
  SliderVisualState,
@@ -63,18 +64,21 @@ const SLIDER_CONTENT_INSET: f32 = 1.0;
63
64
  const SLIDER_OUTER_INSET: f32 = SLIDER_CHROME_INSET + SLIDER_CONTENT_INSET;
64
65
  const SLIDER_CHILD_INSET: f32 = SLIDER_PADDING + SLIDER_CONTENT_INSET;
65
66
 
66
- function createSliderPresenter(template: SliderTemplate | null): SliderPresenter {
67
+ function createSliderPresenter(template: SliderTemplate | null, sizing: SliderSizing | null = null): SliderPresenter {
67
68
  if (template !== null) {
68
69
  return template.create();
69
70
  }
70
71
  const templateSet = getControlTemplates();
71
72
  const appTemplate = templateSet !== null ? templateSet.slider : null;
72
- return (appTemplate === null ? defaultSliderTemplate : appTemplate).create();
73
+ return appTemplate === null
74
+ ? createDefaultSliderPresenter(sizing)
75
+ : appTemplate.create();
73
76
  }
74
77
 
75
78
  export class Slider extends FlexBox implements DragGestureHost {
76
- private sliderPresenter: SliderPresenter = createSliderPresenter(null);
79
+ private sliderPresenter: SliderPresenter = createSliderPresenter(null, null);
77
80
  private templateOverride: SliderTemplate | null = null;
81
+ private sizingValue: SliderSizing | null = null;
78
82
  private readonly disposables: Array<Disposable> = new Array<Disposable>();
79
83
  private readonly dragGesture!: DragGesture;
80
84
  private changedCallback: ((value: f32) => void) | null = null;
@@ -172,9 +176,23 @@ export class Slider extends FlexBox implements DragGestureHost {
172
176
  return this;
173
177
  }
174
178
 
179
+ sizing(sizing: SliderSizing | null): this {
180
+ this.sizingValue = sizing;
181
+ if (!this.usesDefaultPresenter()) {
182
+ return this;
183
+ }
184
+ this.replacePresenter(createSliderPresenter(this.templateOverride, this.sizingValue));
185
+ const thumbSize = this.sliderPresenter.metrics.thumbSize;
186
+ if (this.lengthValue <= thumbSize) {
187
+ this.lengthValue = thumbSize + 1.0;
188
+ }
189
+ this.syncPresentation();
190
+ return this;
191
+ }
192
+
175
193
  template(template: SliderTemplate | null): this {
176
194
  this.templateOverride = template;
177
- const nextPresenter = createSliderPresenter(this.templateOverride);
195
+ const nextPresenter = createSliderPresenter(this.templateOverride, this.sizingValue);
178
196
  this.replacePresenter(nextPresenter);
179
197
  const thumbSize = this.sliderPresenter.metrics.thumbSize;
180
198
  if (this.lengthValue <= thumbSize) {
@@ -447,6 +465,14 @@ export class Slider extends FlexBox implements DragGestureHost {
447
465
  previousRoot.dispose();
448
466
  }
449
467
 
468
+ private usesDefaultPresenter(): bool {
469
+ if (this.templateOverride !== null) {
470
+ return false;
471
+ }
472
+ const templateSet = getControlTemplates();
473
+ return templateSet === null || templateSet.slider === null;
474
+ }
475
+
450
476
  private track(disposable: Disposable): void {
451
477
  this.disposables.push(disposable);
452
478
  }
@@ -1,5 +1,6 @@
1
1
  export { Button } from "./Button";
2
2
  export { Checkbox } from "./Checkbox";
3
+ export { DropdownSizing, LabeledControlSizing, SliderSizing } from "./ControlSizing";
3
4
  export { ContextMenu, MenuItem } from "./ContextMenu";
4
5
  export { Dialog } from "./Dialog";
5
6
  export { Dropdown, DropdownItem } from "./Dropdown";