@effindomv2/fui-as 0.1.12 → 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 +1 -1
- package/src/Fui.ts +4 -0
- package/src/controls/Checkbox.ts +29 -4
- package/src/controls/ControlSizing.ts +158 -0
- package/src/controls/Dropdown.ts +87 -20
- package/src/controls/RadioButton.ts +29 -4
- package/src/controls/Slider.ts +31 -5
- package/src/controls/index.ts +1 -0
- package/src/controls/internal/CheckboxIndicatorPresenter.ts +45 -8
- package/src/controls/internal/DropdownChevronPresenter.ts +32 -5
- package/src/controls/internal/DropdownFieldPresenter.ts +69 -8
- package/src/controls/internal/DropdownOptionRowPresenter.ts +38 -6
- package/src/controls/internal/PressableLabeledControl.ts +10 -1
- package/src/controls/internal/RadioIndicatorPresenter.ts +59 -13
- package/src/controls/internal/SliderPresenter.ts +62 -22
- package/src/controls/templating.ts +1 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { BorderStyle, Orientation, Unit } from "../../core/ffi";
|
|
2
2
|
import { Theme } from "../../core/Theme";
|
|
3
3
|
import { FlexBox } from "../../nodes";
|
|
4
|
+
import { SliderSizing } from "../ControlSizing";
|
|
4
5
|
|
|
5
6
|
function clamp(value: f32, min: f32, max: f32): f32 {
|
|
6
7
|
if (value < min) {
|
|
@@ -12,6 +13,18 @@ function clamp(value: f32, min: f32, max: f32): f32 {
|
|
|
12
13
|
return value;
|
|
13
14
|
}
|
|
14
15
|
|
|
16
|
+
function resolveThumbSize(metrics: SliderPresenterMetrics): f32 {
|
|
17
|
+
return metrics.thumbSize > 1.0 ? metrics.thumbSize : 1.0;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function resolveTrackThickness(metrics: SliderPresenterMetrics): f32 {
|
|
21
|
+
return clamp(metrics.trackThickness, 1.0, resolveThumbSize(metrics));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function resolveCrossAxisExtra(metrics: SliderPresenterMetrics): f32 {
|
|
25
|
+
return metrics.crossAxisExtra > 0.0 ? metrics.crossAxisExtra : 0.0;
|
|
26
|
+
}
|
|
27
|
+
|
|
15
28
|
export class SliderPresenterMetrics {
|
|
16
29
|
constructor(
|
|
17
30
|
readonly thumbSize: f32,
|
|
@@ -20,6 +33,20 @@ export class SliderPresenterMetrics {
|
|
|
20
33
|
) {}
|
|
21
34
|
}
|
|
22
35
|
|
|
36
|
+
const DEFAULT_SLIDER_METRICS = new SliderPresenterMetrics(18.0, 6.0, 2.0);
|
|
37
|
+
|
|
38
|
+
function resolveSliderMetrics(sizing: SliderSizing | null): SliderPresenterMetrics {
|
|
39
|
+
if (sizing === null) {
|
|
40
|
+
return DEFAULT_SLIDER_METRICS;
|
|
41
|
+
}
|
|
42
|
+
const thumbSize = sizing.hasThumbSize ? sizing.thumbSizePx : DEFAULT_SLIDER_METRICS.thumbSize;
|
|
43
|
+
const trackThickness = sizing.hasTrackThickness ? sizing.trackThicknessPx : DEFAULT_SLIDER_METRICS.trackThickness;
|
|
44
|
+
if (thumbSize == DEFAULT_SLIDER_METRICS.thumbSize && trackThickness == DEFAULT_SLIDER_METRICS.trackThickness) {
|
|
45
|
+
return DEFAULT_SLIDER_METRICS;
|
|
46
|
+
}
|
|
47
|
+
return new SliderPresenterMetrics(thumbSize, trackThickness, DEFAULT_SLIDER_METRICS.crossAxisExtra);
|
|
48
|
+
}
|
|
49
|
+
|
|
23
50
|
export class SliderVisualState {
|
|
24
51
|
constructor(
|
|
25
52
|
readonly value: f32,
|
|
@@ -61,15 +88,15 @@ class DefaultSliderPresenter extends SliderPresenter {
|
|
|
61
88
|
private readonly fillNode: FlexBox;
|
|
62
89
|
private readonly thumbNode: FlexBox;
|
|
63
90
|
|
|
64
|
-
constructor() {
|
|
91
|
+
constructor(metrics: SliderPresenterMetrics = DEFAULT_SLIDER_METRICS) {
|
|
65
92
|
const root = new FlexBox();
|
|
66
|
-
super(root,
|
|
93
|
+
super(root, metrics);
|
|
67
94
|
const trackNode = new FlexBox().positionAbsolute();
|
|
68
95
|
const fillNode = new FlexBox().positionAbsolute();
|
|
69
96
|
const thumbNode = new FlexBox()
|
|
70
97
|
.positionAbsolute()
|
|
71
|
-
.width(
|
|
72
|
-
.height(
|
|
98
|
+
.width(metrics.thumbSize, Unit.Pixel)
|
|
99
|
+
.height(metrics.thumbSize, Unit.Pixel);
|
|
73
100
|
this.trackNode = trackNode;
|
|
74
101
|
this.fillNode = fillNode;
|
|
75
102
|
this.thumbNode = thumbNode;
|
|
@@ -81,26 +108,30 @@ class DefaultSliderPresenter extends SliderPresenter {
|
|
|
81
108
|
|
|
82
109
|
layout(state: SliderVisualState, length: f32): void {
|
|
83
110
|
const metrics = this.metrics;
|
|
84
|
-
const
|
|
111
|
+
const thumbSize = resolveThumbSize(metrics);
|
|
112
|
+
const trackThickness = resolveTrackThickness(metrics);
|
|
113
|
+
const crossAxisExtra = resolveCrossAxisExtra(metrics);
|
|
114
|
+
const available = length > thumbSize ? length - thumbSize : 0.0;
|
|
85
115
|
const fraction = clamp(state.normalizedValue, 0.0, 1.0);
|
|
86
|
-
const crossAxisInset =
|
|
116
|
+
const crossAxisInset = crossAxisExtra * 0.5;
|
|
117
|
+
const trackOffset = crossAxisInset + ((thumbSize - trackThickness) * 0.5);
|
|
87
118
|
if (state.orientation == Orientation.Vertical) {
|
|
88
119
|
this.root
|
|
89
|
-
.width(
|
|
120
|
+
.width(thumbSize + crossAxisExtra, Unit.Pixel)
|
|
90
121
|
.height(length, Unit.Pixel);
|
|
91
122
|
this.trackNode
|
|
92
|
-
.width(
|
|
123
|
+
.width(trackThickness, Unit.Pixel)
|
|
93
124
|
.height(available, Unit.Pixel)
|
|
94
125
|
.position(
|
|
95
|
-
|
|
96
|
-
|
|
126
|
+
trackOffset,
|
|
127
|
+
thumbSize * 0.5,
|
|
97
128
|
);
|
|
98
129
|
this.fillNode
|
|
99
|
-
.width(
|
|
130
|
+
.width(trackThickness, Unit.Pixel)
|
|
100
131
|
.height(available * fraction, Unit.Pixel)
|
|
101
132
|
.position(
|
|
102
|
-
|
|
103
|
-
|
|
133
|
+
trackOffset,
|
|
134
|
+
thumbSize * 0.5 + (available * (1.0 - fraction)),
|
|
104
135
|
);
|
|
105
136
|
this.thumbNode.position(
|
|
106
137
|
crossAxisInset,
|
|
@@ -111,20 +142,20 @@ class DefaultSliderPresenter extends SliderPresenter {
|
|
|
111
142
|
|
|
112
143
|
this.root
|
|
113
144
|
.width(length, Unit.Pixel)
|
|
114
|
-
.height(
|
|
145
|
+
.height(thumbSize + crossAxisExtra, Unit.Pixel);
|
|
115
146
|
this.trackNode
|
|
116
147
|
.width(available, Unit.Pixel)
|
|
117
|
-
.height(
|
|
148
|
+
.height(trackThickness, Unit.Pixel)
|
|
118
149
|
.position(
|
|
119
|
-
|
|
120
|
-
|
|
150
|
+
thumbSize * 0.5,
|
|
151
|
+
trackOffset,
|
|
121
152
|
);
|
|
122
153
|
this.fillNode
|
|
123
154
|
.width(available * fraction, Unit.Pixel)
|
|
124
|
-
.height(
|
|
155
|
+
.height(trackThickness, Unit.Pixel)
|
|
125
156
|
.position(
|
|
126
|
-
|
|
127
|
-
|
|
157
|
+
thumbSize * 0.5,
|
|
158
|
+
trackOffset,
|
|
128
159
|
);
|
|
129
160
|
this.thumbNode.position(
|
|
130
161
|
available * fraction,
|
|
@@ -137,12 +168,17 @@ class DefaultSliderPresenter extends SliderPresenter {
|
|
|
137
168
|
? theme.colors.accentPressed
|
|
138
169
|
: (state.hovered ? theme.colors.accentHovered : theme.colors.accent);
|
|
139
170
|
const metrics = this.metrics;
|
|
140
|
-
const
|
|
171
|
+
const thumbSize = resolveThumbSize(metrics);
|
|
172
|
+
const trackThickness = resolveTrackThickness(metrics);
|
|
173
|
+
const trackRadius = trackThickness * 0.5;
|
|
141
174
|
this.trackNode.cornerRadius(trackRadius);
|
|
142
175
|
this.trackNode.bgColor(theme.colors.scrollbarTrack);
|
|
143
176
|
this.fillNode.cornerRadius(trackRadius);
|
|
144
177
|
this.fillNode.bgColor(accent);
|
|
145
|
-
this.thumbNode
|
|
178
|
+
this.thumbNode
|
|
179
|
+
.width(thumbSize, Unit.Pixel)
|
|
180
|
+
.height(thumbSize, Unit.Pixel)
|
|
181
|
+
.cornerRadius(thumbSize * 0.5);
|
|
146
182
|
this.thumbNode.bgColor(accent);
|
|
147
183
|
this.thumbNode.border(1.0, theme.colors.surface, BorderStyle.Solid);
|
|
148
184
|
}
|
|
@@ -155,3 +191,7 @@ class DefaultSliderTemplate extends SliderTemplate {
|
|
|
155
191
|
}
|
|
156
192
|
|
|
157
193
|
export const defaultSliderTemplate = new DefaultSliderTemplate();
|
|
194
|
+
|
|
195
|
+
export function createDefaultSliderPresenter(sizing: SliderSizing | null = null): SliderPresenter {
|
|
196
|
+
return new DefaultSliderPresenter(resolveSliderMetrics(sizing));
|
|
197
|
+
}
|