@effindomv2/fui-as 0.1.25 → 0.1.27
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 +2 -2
- package/src/Fui.ts +4 -0
- package/src/controls/Dropdown.ts +12 -2
- package/src/controls/DropdownColors.ts +61 -0
- package/src/controls/LabeledControlColors.ts +25 -0
- package/src/controls/Slider.ts +9 -1
- package/src/controls/SliderColors.ts +37 -0
- package/src/controls/TextInputColors.ts +85 -0
- package/src/controls/index.ts +4 -0
- package/src/controls/internal/DropdownFieldPresenter.ts +11 -5
- package/src/controls/internal/DropdownOptionRowPresenter.ts +9 -7
- package/src/controls/internal/PressableLabeledControl.ts +24 -1
- package/src/controls/internal/SliderPresenter.ts +9 -5
- package/src/controls/internal/TextInputCore.ts +39 -4
- package/src/controls/internal/TextInputPresenter.ts +7 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@effindomv2/fui-as",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.27",
|
|
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",
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
},
|
|
87
87
|
"dependencies": {
|
|
88
88
|
"@assemblyscript/loader": "^0.28.17",
|
|
89
|
-
"@effindomv2/runtime": "0.1.
|
|
89
|
+
"@effindomv2/runtime": "0.1.10"
|
|
90
90
|
},
|
|
91
91
|
"devDependencies": {
|
|
92
92
|
"@as-pect/assembly": "8.1.0",
|
package/src/Fui.ts
CHANGED
|
@@ -159,6 +159,7 @@ export {
|
|
|
159
159
|
DropdownFieldTemplate,
|
|
160
160
|
DropdownFieldVisualState,
|
|
161
161
|
DropdownItem,
|
|
162
|
+
DropdownColors,
|
|
162
163
|
DropdownOptionRowMetrics,
|
|
163
164
|
DropdownOptionRowPresenter,
|
|
164
165
|
DropdownOptionRowTemplate,
|
|
@@ -168,6 +169,7 @@ export {
|
|
|
168
169
|
MenuItem,
|
|
169
170
|
NavLink,
|
|
170
171
|
LabeledControlSizing,
|
|
172
|
+
LabeledControlColors,
|
|
171
173
|
PressableIndicatorMetrics,
|
|
172
174
|
ProgressBar,
|
|
173
175
|
RadioIndicatorPresenter,
|
|
@@ -178,6 +180,7 @@ export {
|
|
|
178
180
|
SelectionArea,
|
|
179
181
|
Slider,
|
|
180
182
|
SliderSizing,
|
|
183
|
+
SliderColors,
|
|
181
184
|
SliderPresenter,
|
|
182
185
|
SliderPresenterMetrics,
|
|
183
186
|
SliderTemplate,
|
|
@@ -190,6 +193,7 @@ export {
|
|
|
190
193
|
TextInputPresenter,
|
|
191
194
|
TextInput,
|
|
192
195
|
TextInputTemplate,
|
|
196
|
+
TextInputColors,
|
|
193
197
|
TextInputVisualState,
|
|
194
198
|
useControlTemplates,
|
|
195
199
|
} from "./controls";
|
package/src/controls/Dropdown.ts
CHANGED
|
@@ -23,6 +23,7 @@ import { registerScrollHook } from "../core/ScrollHooks";
|
|
|
23
23
|
import { FlexBox, Portal, ScrollBarVisibility, ScrollBox, ScrollView } from "../nodes";
|
|
24
24
|
import { bind2 } from "../core/bind";
|
|
25
25
|
import { DropdownSizing } from "./ControlSizing";
|
|
26
|
+
import { DropdownColors } from "./DropdownColors";
|
|
26
27
|
import { getControlTemplates } from "./ControlTemplateSet";
|
|
27
28
|
import {
|
|
28
29
|
createDefaultDropdownChevronPresenter,
|
|
@@ -158,10 +159,10 @@ class DropdownOptionNode extends FlexBox {
|
|
|
158
159
|
return this.presenter.metrics.height;
|
|
159
160
|
}
|
|
160
161
|
|
|
161
|
-
applyTheme(theme: Theme, highlighted: bool, selected: bool, enabled: bool): void {
|
|
162
|
+
applyTheme(theme: Theme, highlighted: bool, selected: bool, enabled: bool, colors: DropdownColors | null): void {
|
|
162
163
|
this.semanticSelected(selected);
|
|
163
164
|
this.semanticDisabled(!enabled);
|
|
164
|
-
this.presenter.apply(theme, new DropdownOptionRowVisualState(highlighted, selected, enabled));
|
|
165
|
+
this.presenter.apply(theme, new DropdownOptionRowVisualState(highlighted, selected, enabled), colors);
|
|
165
166
|
}
|
|
166
167
|
|
|
167
168
|
_handlePointerEvent(eventType: PointerEventType, x: f32, y: f32, modifiers: u32 = 0): void {
|
|
@@ -193,6 +194,7 @@ export class Dropdown extends FlexBox implements GlobalKeyHandler {
|
|
|
193
194
|
private chevronTemplateValue: DropdownChevronTemplate | null = null;
|
|
194
195
|
private optionRowTemplateValue: DropdownOptionRowTemplate | null = null;
|
|
195
196
|
private sizingValue: DropdownSizing | null = null;
|
|
197
|
+
private colorsValue: DropdownColors | null = null;
|
|
196
198
|
private fieldPresenter: DropdownFieldPresenter;
|
|
197
199
|
private chevronPresenter: DropdownChevronPresenter;
|
|
198
200
|
private readonly popupRoot: Portal;
|
|
@@ -375,6 +377,12 @@ export class Dropdown extends FlexBox implements GlobalKeyHandler {
|
|
|
375
377
|
return this;
|
|
376
378
|
}
|
|
377
379
|
|
|
380
|
+
colors(colors: DropdownColors | null): this {
|
|
381
|
+
this.colorsValue = colors;
|
|
382
|
+
this.handleThemeChanged();
|
|
383
|
+
return this;
|
|
384
|
+
}
|
|
385
|
+
|
|
378
386
|
fieldTemplate(template: DropdownFieldTemplate | null): this {
|
|
379
387
|
this.close();
|
|
380
388
|
this.fieldTemplateValue = template;
|
|
@@ -768,6 +776,7 @@ export class Dropdown extends FlexBox implements GlobalKeyHandler {
|
|
|
768
776
|
index == this.highlightedIndexValue,
|
|
769
777
|
index == this.selectedIndexValue,
|
|
770
778
|
this.isEnabled,
|
|
779
|
+
this.colorsValue,
|
|
771
780
|
);
|
|
772
781
|
}
|
|
773
782
|
}
|
|
@@ -904,6 +913,7 @@ export class Dropdown extends FlexBox implements GlobalKeyHandler {
|
|
|
904
913
|
? unchecked(this.itemsValue[this.selectedIndexValue]).label
|
|
905
914
|
: "",
|
|
906
915
|
),
|
|
916
|
+
this.colorsValue,
|
|
907
917
|
);
|
|
908
918
|
this.chevronPresenter.apply(
|
|
909
919
|
theme,
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
export class DropdownColors {
|
|
2
|
+
private backgroundSet: bool = false;
|
|
3
|
+
private backgroundValue: u32 = 0;
|
|
4
|
+
|
|
5
|
+
private textPrimarySet: bool = false;
|
|
6
|
+
private textPrimaryValue: u32 = 0;
|
|
7
|
+
|
|
8
|
+
private placeholderSet: bool = false;
|
|
9
|
+
private placeholderValue: u32 = 0;
|
|
10
|
+
|
|
11
|
+
private borderSet: bool = false;
|
|
12
|
+
private borderValue: u32 = 0;
|
|
13
|
+
|
|
14
|
+
private accentSet: bool = false;
|
|
15
|
+
private accentValue: u32 = 0;
|
|
16
|
+
|
|
17
|
+
background(color: u32): this {
|
|
18
|
+
this.backgroundValue = color;
|
|
19
|
+
this.backgroundSet = true;
|
|
20
|
+
return this;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
textPrimary(color: u32): this {
|
|
24
|
+
this.textPrimaryValue = color;
|
|
25
|
+
this.textPrimarySet = true;
|
|
26
|
+
return this;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
placeholder(color: u32): this {
|
|
30
|
+
this.placeholderValue = color;
|
|
31
|
+
this.placeholderSet = true;
|
|
32
|
+
return this;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
border(color: u32): this {
|
|
36
|
+
this.borderValue = color;
|
|
37
|
+
this.borderSet = true;
|
|
38
|
+
return this;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
accent(color: u32): this {
|
|
42
|
+
this.accentValue = color;
|
|
43
|
+
this.accentSet = true;
|
|
44
|
+
return this;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
get hasBackground(): bool { return this.backgroundSet; }
|
|
48
|
+
get backgroundColor(): u32 { return this.backgroundValue; }
|
|
49
|
+
|
|
50
|
+
get hasTextPrimary(): bool { return this.textPrimarySet; }
|
|
51
|
+
get textPrimaryColor(): u32 { return this.textPrimaryValue; }
|
|
52
|
+
|
|
53
|
+
get hasPlaceholder(): bool { return this.placeholderSet; }
|
|
54
|
+
get placeholderColor(): u32 { return this.placeholderValue; }
|
|
55
|
+
|
|
56
|
+
get hasBorder(): bool { return this.borderSet; }
|
|
57
|
+
get borderColor(): u32 { return this.borderValue; }
|
|
58
|
+
|
|
59
|
+
get hasAccent(): bool { return this.accentSet; }
|
|
60
|
+
get accentColor(): u32 { return this.accentValue; }
|
|
61
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export class LabeledControlColors {
|
|
2
|
+
private textPrimarySet: bool = false;
|
|
3
|
+
private textPrimaryValue: u32 = 0;
|
|
4
|
+
|
|
5
|
+
private textMutedSet: bool = false;
|
|
6
|
+
private textMutedValue: u32 = 0;
|
|
7
|
+
|
|
8
|
+
textPrimary(color: u32): this {
|
|
9
|
+
this.textPrimaryValue = color;
|
|
10
|
+
this.textPrimarySet = true;
|
|
11
|
+
return this;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
textMuted(color: u32): this {
|
|
15
|
+
this.textMutedValue = color;
|
|
16
|
+
this.textMutedSet = true;
|
|
17
|
+
return this;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
get hasTextPrimary(): bool { return this.textPrimarySet; }
|
|
21
|
+
get textPrimaryColor(): u32 { return this.textPrimaryValue; }
|
|
22
|
+
|
|
23
|
+
get hasTextMuted(): bool { return this.textMutedSet; }
|
|
24
|
+
get textMutedColor(): u32 { return this.textMutedValue; }
|
|
25
|
+
}
|
package/src/controls/Slider.ts
CHANGED
|
@@ -21,6 +21,7 @@ import { Node } from "../core/Node";
|
|
|
21
21
|
import { FlexBox } from "../nodes";
|
|
22
22
|
import { bind1 } from "../core/bind";
|
|
23
23
|
import { SliderSizing } from "./ControlSizing";
|
|
24
|
+
import { SliderColors } from "./SliderColors";
|
|
24
25
|
import { getControlTemplates } from "./ControlTemplateSet";
|
|
25
26
|
import {
|
|
26
27
|
createDefaultSliderPresenter,
|
|
@@ -79,6 +80,7 @@ export class Slider extends FlexBox implements DragGestureHost {
|
|
|
79
80
|
private sliderPresenter: SliderPresenter = createSliderPresenter(null, null);
|
|
80
81
|
private templateOverride: SliderTemplate | null = null;
|
|
81
82
|
private sizingValue: SliderSizing | null = null;
|
|
83
|
+
private colorsValue: SliderColors | null = null;
|
|
82
84
|
private readonly disposables: Array<Disposable> = new Array<Disposable>();
|
|
83
85
|
private readonly dragGesture!: DragGesture;
|
|
84
86
|
private changedCallback: ((value: f32) => void) | null = null;
|
|
@@ -190,6 +192,12 @@ export class Slider extends FlexBox implements DragGestureHost {
|
|
|
190
192
|
return this;
|
|
191
193
|
}
|
|
192
194
|
|
|
195
|
+
colors(colors: SliderColors | null): this {
|
|
196
|
+
this.colorsValue = colors;
|
|
197
|
+
this.syncPresentation();
|
|
198
|
+
return this;
|
|
199
|
+
}
|
|
200
|
+
|
|
193
201
|
template(template: SliderTemplate | null): this {
|
|
194
202
|
this.templateOverride = template;
|
|
195
203
|
const nextPresenter = createSliderPresenter(this.templateOverride, this.sizingValue);
|
|
@@ -398,7 +406,7 @@ export class Slider extends FlexBox implements DragGestureHost {
|
|
|
398
406
|
);
|
|
399
407
|
this.padding(SLIDER_PADDING, SLIDER_PADDING, SLIDER_PADDING, SLIDER_PADDING);
|
|
400
408
|
this.opacity(this.isEnabled ? 1.0 : 0.6);
|
|
401
|
-
this.sliderPresenter.apply(theme, state);
|
|
409
|
+
this.sliderPresenter.apply(theme, state, this.colorsValue);
|
|
402
410
|
}
|
|
403
411
|
|
|
404
412
|
private syncVisualState(): void {
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export class SliderColors {
|
|
2
|
+
private trackSet: bool = false;
|
|
3
|
+
private trackValue: u32 = 0;
|
|
4
|
+
|
|
5
|
+
private fillSet: bool = false;
|
|
6
|
+
private fillValue: u32 = 0;
|
|
7
|
+
|
|
8
|
+
private thumbSet: bool = false;
|
|
9
|
+
private thumbValue: u32 = 0;
|
|
10
|
+
|
|
11
|
+
track(color: u32): this {
|
|
12
|
+
this.trackValue = color;
|
|
13
|
+
this.trackSet = true;
|
|
14
|
+
return this;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
fill(color: u32): this {
|
|
18
|
+
this.fillValue = color;
|
|
19
|
+
this.fillSet = true;
|
|
20
|
+
return this;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
thumb(color: u32): this {
|
|
24
|
+
this.thumbValue = color;
|
|
25
|
+
this.thumbSet = true;
|
|
26
|
+
return this;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
get hasTrack(): bool { return this.trackSet; }
|
|
30
|
+
get trackColor(): u32 { return this.trackValue; }
|
|
31
|
+
|
|
32
|
+
get hasFill(): bool { return this.fillSet; }
|
|
33
|
+
get fillColor(): u32 { return this.fillValue; }
|
|
34
|
+
|
|
35
|
+
get hasThumb(): bool { return this.thumbSet; }
|
|
36
|
+
get thumbColor(): u32 { return this.thumbValue; }
|
|
37
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
export class TextInputColors {
|
|
2
|
+
private backgroundSet: bool = false;
|
|
3
|
+
private backgroundValue: u32 = 0;
|
|
4
|
+
|
|
5
|
+
private textPrimarySet: bool = false;
|
|
6
|
+
private textPrimaryValue: u32 = 0;
|
|
7
|
+
|
|
8
|
+
private textMutedSet: bool = false;
|
|
9
|
+
private textMutedValue: u32 = 0;
|
|
10
|
+
|
|
11
|
+
private placeholderSet: bool = false;
|
|
12
|
+
private placeholderValue: u32 = 0;
|
|
13
|
+
|
|
14
|
+
private caretSet: bool = false;
|
|
15
|
+
private caretValue: u32 = 0;
|
|
16
|
+
|
|
17
|
+
private borderSet: bool = false;
|
|
18
|
+
private borderValue: u32 = 0;
|
|
19
|
+
|
|
20
|
+
private accentSet: bool = false;
|
|
21
|
+
private accentValue: u32 = 0;
|
|
22
|
+
|
|
23
|
+
background(color: u32): this {
|
|
24
|
+
this.backgroundValue = color;
|
|
25
|
+
this.backgroundSet = true;
|
|
26
|
+
return this;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
textPrimary(color: u32): this {
|
|
30
|
+
this.textPrimaryValue = color;
|
|
31
|
+
this.textPrimarySet = true;
|
|
32
|
+
return this;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
textMuted(color: u32): this {
|
|
36
|
+
this.textMutedValue = color;
|
|
37
|
+
this.textMutedSet = true;
|
|
38
|
+
return this;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
placeholder(color: u32): this {
|
|
42
|
+
this.placeholderValue = color;
|
|
43
|
+
this.placeholderSet = true;
|
|
44
|
+
return this;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
caret(color: u32): this {
|
|
48
|
+
this.caretValue = color;
|
|
49
|
+
this.caretSet = true;
|
|
50
|
+
return this;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
border(color: u32): this {
|
|
54
|
+
this.borderValue = color;
|
|
55
|
+
this.borderSet = true;
|
|
56
|
+
return this;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
accent(color: u32): this {
|
|
60
|
+
this.accentValue = color;
|
|
61
|
+
this.accentSet = true;
|
|
62
|
+
return this;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
get hasBackground(): bool { return this.backgroundSet; }
|
|
66
|
+
get backgroundColor(): u32 { return this.backgroundValue; }
|
|
67
|
+
|
|
68
|
+
get hasTextPrimary(): bool { return this.textPrimarySet; }
|
|
69
|
+
get textPrimaryColor(): u32 { return this.textPrimaryValue; }
|
|
70
|
+
|
|
71
|
+
get hasTextMuted(): bool { return this.textMutedSet; }
|
|
72
|
+
get textMutedColor(): u32 { return this.textMutedValue; }
|
|
73
|
+
|
|
74
|
+
get hasPlaceholder(): bool { return this.placeholderSet; }
|
|
75
|
+
get placeholderColor(): u32 { return this.placeholderValue; }
|
|
76
|
+
|
|
77
|
+
get hasCaret(): bool { return this.caretSet; }
|
|
78
|
+
get caretColor(): u32 { return this.caretValue; }
|
|
79
|
+
|
|
80
|
+
get hasBorder(): bool { return this.borderSet; }
|
|
81
|
+
get borderColor(): u32 { return this.borderValue; }
|
|
82
|
+
|
|
83
|
+
get hasAccent(): bool { return this.accentSet; }
|
|
84
|
+
get accentColor(): u32 { return this.accentValue; }
|
|
85
|
+
}
|
package/src/controls/index.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
export { Button } from "./Button";
|
|
2
2
|
export { Checkbox } from "./Checkbox";
|
|
3
3
|
export { DropdownSizing, LabeledControlSizing, SliderSizing } from "./ControlSizing";
|
|
4
|
+
export { LabeledControlColors } from "./LabeledControlColors";
|
|
5
|
+
export { TextInputColors } from "./TextInputColors";
|
|
6
|
+
export { DropdownColors } from "./DropdownColors";
|
|
7
|
+
export { SliderColors } from "./SliderColors";
|
|
4
8
|
export { ContextMenu, MenuItem } from "./ContextMenu";
|
|
5
9
|
export { Dialog } from "./Dialog";
|
|
6
10
|
export { Dropdown, DropdownItem } from "./Dropdown";
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
import { Theme } from "../../core/Theme";
|
|
10
10
|
import { FlexBox, Text } from "../../nodes";
|
|
11
11
|
import { DropdownSizing } from "../ControlSizing";
|
|
12
|
+
import { DropdownColors } from "../DropdownColors";
|
|
12
13
|
|
|
13
14
|
const DEFAULT_CHEVRON_BOX_SIZE: f32 = 16.0;
|
|
14
15
|
const DEFAULT_FIELD_PADDING_X: f32 = 16.0;
|
|
@@ -98,7 +99,7 @@ export abstract class DropdownFieldPresenter {
|
|
|
98
99
|
return this.metricsValue;
|
|
99
100
|
}
|
|
100
101
|
|
|
101
|
-
abstract apply(theme: Theme, state: DropdownFieldVisualState): void;
|
|
102
|
+
abstract apply(theme: Theme, state: DropdownFieldVisualState, colors?: DropdownColors | null): void;
|
|
102
103
|
}
|
|
103
104
|
|
|
104
105
|
export abstract class DropdownFieldTemplate {
|
|
@@ -131,26 +132,31 @@ class DefaultDropdownFieldPresenter extends DropdownFieldPresenter {
|
|
|
131
132
|
super(root, valueHost, valueNode, chevronHost, metrics);
|
|
132
133
|
}
|
|
133
134
|
|
|
134
|
-
apply(theme: Theme, state: DropdownFieldVisualState): void {
|
|
135
|
+
apply(theme: Theme, state: DropdownFieldVisualState, colors: DropdownColors | null = null): void {
|
|
135
136
|
const metrics = this.metrics;
|
|
136
137
|
const contentHeight = <f32>Math.max(
|
|
137
138
|
metrics.fontSize,
|
|
138
139
|
metrics.height - metrics.paddingTop - metrics.paddingBottom,
|
|
139
140
|
);
|
|
141
|
+
const bg = colors !== null && colors.hasBackground ? colors.backgroundColor : (state.pressed && state.enabled ? theme.colors.background : theme.colors.surface);
|
|
142
|
+
const borderColor = colors !== null && colors.hasBorder ? colors.borderColor : theme.colors.border;
|
|
140
143
|
this.root
|
|
141
144
|
.flexDirection(FlexDirection.Row)
|
|
142
145
|
.alignItems(AlignItems.Center)
|
|
143
146
|
.height(metrics.height, Unit.Pixel)
|
|
144
147
|
.cornerRadius(theme.spacing.sm)
|
|
145
|
-
.border(2.0,
|
|
148
|
+
.border(2.0, borderColor, BorderStyle.Solid)
|
|
146
149
|
.padding(metrics.paddingLeft, metrics.paddingTop, metrics.paddingRight, metrics.paddingBottom)
|
|
147
|
-
.bgColor(
|
|
150
|
+
.bgColor(bg);
|
|
148
151
|
this.valueHost
|
|
149
152
|
.fillSize();
|
|
153
|
+
const textColor = !state.enabled
|
|
154
|
+
? theme.colors.textMuted
|
|
155
|
+
: (colors !== null && colors.hasTextPrimary ? colors.textPrimaryColor : theme.colors.textPrimary);
|
|
150
156
|
this.valueNode
|
|
151
157
|
.font(theme.fonts.body, metrics.fontSize)
|
|
152
158
|
.lineHeight(contentHeight)
|
|
153
|
-
.textColor(
|
|
159
|
+
.textColor(textColor);
|
|
154
160
|
this.chevronHost
|
|
155
161
|
.width(metrics.chevronBoxSize, Unit.Pixel)
|
|
156
162
|
.height(metrics.chevronBoxSize, Unit.Pixel)
|
|
@@ -2,6 +2,7 @@ import { AlignItems, TextVerticalAlign } from "../../core/ffi";
|
|
|
2
2
|
import { Theme } from "../../core/Theme";
|
|
3
3
|
import { FlexBox, Text } from "../../nodes";
|
|
4
4
|
import { DropdownSizing } from "../ControlSizing";
|
|
5
|
+
import { DropdownColors } from "../DropdownColors";
|
|
5
6
|
|
|
6
7
|
export class DropdownOptionRowMetrics {
|
|
7
8
|
constructor(
|
|
@@ -55,7 +56,7 @@ export abstract class DropdownOptionRowPresenter {
|
|
|
55
56
|
return this.metricsValue;
|
|
56
57
|
}
|
|
57
58
|
|
|
58
|
-
abstract apply(theme: Theme, state: DropdownOptionRowVisualState): void;
|
|
59
|
+
abstract apply(theme: Theme, state: DropdownOptionRowVisualState, colors?: DropdownColors | null): void;
|
|
59
60
|
}
|
|
60
61
|
|
|
61
62
|
export abstract class DropdownOptionRowTemplate {
|
|
@@ -79,19 +80,20 @@ class DefaultDropdownOptionRowPresenter extends DropdownOptionRowPresenter {
|
|
|
79
80
|
super(root, labelNode, metrics);
|
|
80
81
|
}
|
|
81
82
|
|
|
82
|
-
apply(theme: Theme, state: DropdownOptionRowVisualState): void {
|
|
83
|
+
apply(theme: Theme, state: DropdownOptionRowVisualState, colors: DropdownColors | null = null): void {
|
|
83
84
|
const metrics = this.metrics;
|
|
84
85
|
this.root
|
|
85
86
|
.padding(metrics.paddingLeft, 0.0, metrics.paddingRight, 0.0)
|
|
86
87
|
.cornerRadius(theme.spacing.xs)
|
|
87
88
|
.bgColor(state.highlighted ? theme.contextMenu.item.hoverBackground : 0x00000000);
|
|
89
|
+
const labelColor = !state.enabled
|
|
90
|
+
? theme.colors.textMuted
|
|
91
|
+
: (state.selected
|
|
92
|
+
? (colors !== null && colors.hasAccent ? colors.accentColor : theme.colors.accent)
|
|
93
|
+
: (colors !== null && colors.hasTextPrimary ? colors.textPrimaryColor : theme.colors.textPrimary));
|
|
88
94
|
this.labelNode
|
|
89
95
|
.font(theme.fonts.body, metrics.fontSize)
|
|
90
|
-
.textColor(
|
|
91
|
-
!state.enabled
|
|
92
|
-
? theme.colors.textMuted
|
|
93
|
-
: (state.selected ? theme.colors.accent : theme.colors.textPrimary),
|
|
94
|
-
);
|
|
96
|
+
.textColor(labelColor);
|
|
95
97
|
}
|
|
96
98
|
}
|
|
97
99
|
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
} from "../../core/ffi";
|
|
17
17
|
import { Theme, activeTheme } from "../../core/Theme";
|
|
18
18
|
import { FlexBox, TextCore } from "../../nodes";
|
|
19
|
+
import { LabeledControlColors } from "../LabeledControlColors";
|
|
19
20
|
|
|
20
21
|
const TRANSPARENT: u32 = rgba(0x00, 0x00, 0x00, 0x00);
|
|
21
22
|
|
|
@@ -31,6 +32,7 @@ export class PressableLabeledControl extends FlexBox {
|
|
|
31
32
|
private readonly disposables: Array<Disposable> = new Array<Disposable>();
|
|
32
33
|
private disposed: bool = false;
|
|
33
34
|
private labelFontSizeOverride: f32 = 0.0;
|
|
35
|
+
private colorsValue: LabeledControlColors | null = null;
|
|
34
36
|
protected hoveredState: bool = false;
|
|
35
37
|
protected pressedState: bool = false;
|
|
36
38
|
protected focusedState: bool = false;
|
|
@@ -177,6 +179,12 @@ export class PressableLabeledControl extends FlexBox {
|
|
|
177
179
|
this.syncBaseTheme(activeTheme.value);
|
|
178
180
|
}
|
|
179
181
|
|
|
182
|
+
colors(colors: LabeledControlColors | null): this {
|
|
183
|
+
this.colorsValue = colors;
|
|
184
|
+
this.syncBaseTheme(activeTheme.value);
|
|
185
|
+
return this;
|
|
186
|
+
}
|
|
187
|
+
|
|
180
188
|
protected syncBaseTheme(theme: Theme): void {
|
|
181
189
|
this.cursor(this.isEnabled ? CursorStyle.Pointer : CursorStyle.Default);
|
|
182
190
|
this.cornerRadius(theme.spacing.sm);
|
|
@@ -192,7 +200,22 @@ export class PressableLabeledControl extends FlexBox {
|
|
|
192
200
|
theme.fonts.body,
|
|
193
201
|
this.labelFontSizeOverride > 0.0 ? this.labelFontSizeOverride : theme.fonts.sizeBody,
|
|
194
202
|
);
|
|
195
|
-
|
|
203
|
+
const colors = this.colorsValue;
|
|
204
|
+
let labelColor: u32;
|
|
205
|
+
if (this.isEnabled) {
|
|
206
|
+
if (colors !== null && colors.hasTextPrimary) {
|
|
207
|
+
labelColor = colors.textPrimaryColor;
|
|
208
|
+
} else {
|
|
209
|
+
labelColor = theme.colors.textPrimary;
|
|
210
|
+
}
|
|
211
|
+
} else {
|
|
212
|
+
if (colors !== null && colors.hasTextMuted) {
|
|
213
|
+
labelColor = colors.textMutedColor;
|
|
214
|
+
} else {
|
|
215
|
+
labelColor = theme.colors.textMuted;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
this.labelNode.textColor(labelColor);
|
|
196
219
|
this.syncFocusChrome(theme);
|
|
197
220
|
}
|
|
198
221
|
|
|
@@ -2,6 +2,7 @@ import { BorderStyle, Orientation, Unit } from "../../core/ffi";
|
|
|
2
2
|
import { Theme } from "../../core/Theme";
|
|
3
3
|
import { FlexBox } from "../../nodes";
|
|
4
4
|
import { SliderSizing } from "../ControlSizing";
|
|
5
|
+
import { SliderColors } from "../SliderColors";
|
|
5
6
|
|
|
6
7
|
function clamp(value: f32, min: f32, max: f32): f32 {
|
|
7
8
|
if (value < min) {
|
|
@@ -76,7 +77,7 @@ export abstract class SliderPresenter {
|
|
|
76
77
|
}
|
|
77
78
|
|
|
78
79
|
abstract layout(state: SliderVisualState, length: f32): void;
|
|
79
|
-
abstract apply(theme: Theme, state: SliderVisualState): void;
|
|
80
|
+
abstract apply(theme: Theme, state: SliderVisualState, colors?: SliderColors | null): void;
|
|
80
81
|
}
|
|
81
82
|
|
|
82
83
|
export abstract class SliderTemplate {
|
|
@@ -163,7 +164,7 @@ class DefaultSliderPresenter extends SliderPresenter {
|
|
|
163
164
|
);
|
|
164
165
|
}
|
|
165
166
|
|
|
166
|
-
apply(theme: Theme, state: SliderVisualState): void {
|
|
167
|
+
apply(theme: Theme, state: SliderVisualState, colors: SliderColors | null = null): void {
|
|
167
168
|
const accent = state.dragging
|
|
168
169
|
? theme.colors.accentPressed
|
|
169
170
|
: (state.hovered ? theme.colors.accentHovered : theme.colors.accent);
|
|
@@ -172,14 +173,17 @@ class DefaultSliderPresenter extends SliderPresenter {
|
|
|
172
173
|
const trackThickness = resolveTrackThickness(metrics);
|
|
173
174
|
const trackRadius = trackThickness * 0.5;
|
|
174
175
|
this.trackNode.cornerRadius(trackRadius);
|
|
175
|
-
|
|
176
|
+
const trackColor = colors !== null && colors.hasTrack ? colors.trackColor : theme.colors.scrollbarTrack;
|
|
177
|
+
this.trackNode.bgColor(trackColor);
|
|
176
178
|
this.fillNode.cornerRadius(trackRadius);
|
|
177
|
-
|
|
179
|
+
const fillColor = colors !== null && colors.hasFill ? colors.fillColor : accent;
|
|
180
|
+
this.fillNode.bgColor(fillColor);
|
|
178
181
|
this.thumbNode
|
|
179
182
|
.width(thumbSize, Unit.Pixel)
|
|
180
183
|
.height(thumbSize, Unit.Pixel)
|
|
181
184
|
.cornerRadius(thumbSize * 0.5);
|
|
182
|
-
|
|
185
|
+
const thumbColor = colors !== null && colors.hasThumb ? colors.thumbColor : accent;
|
|
186
|
+
this.thumbNode.bgColor(thumbColor);
|
|
183
187
|
this.thumbNode.border(1.0, theme.colors.surface, BorderStyle.Solid);
|
|
184
188
|
}
|
|
185
189
|
}
|
|
@@ -22,6 +22,7 @@ import { bind1, bind2 } from "../../core/bind";
|
|
|
22
22
|
import { ScrollState } from "../../nodes/ScrollState";
|
|
23
23
|
import { ScrollView } from "../../nodes/ScrollView";
|
|
24
24
|
import { getControlTemplates } from "../ControlTemplateSet";
|
|
25
|
+
import { TextInputColors } from "../TextInputColors";
|
|
25
26
|
import {
|
|
26
27
|
defaultTextInputTemplate,
|
|
27
28
|
TextInputPresenter,
|
|
@@ -179,6 +180,7 @@ export class TextInputCore extends FlexBox {
|
|
|
179
180
|
private focusChangedListener: ((focused: bool) => void) | null = null;
|
|
180
181
|
private textInputFocusChangedBinding: Callback1<bool> | null = null;
|
|
181
182
|
private templateValue: TextInputTemplate | null = null;
|
|
183
|
+
private colorsValue: TextInputColors | null = null;
|
|
182
184
|
|
|
183
185
|
constructor(profile: TextInputProfile, text: string = "") {
|
|
184
186
|
super();
|
|
@@ -256,6 +258,12 @@ export class TextInputCore extends FlexBox {
|
|
|
256
258
|
return this;
|
|
257
259
|
}
|
|
258
260
|
|
|
261
|
+
colors(colors: TextInputColors | null): this {
|
|
262
|
+
this.colorsValue = colors;
|
|
263
|
+
this.syncThemeState(activeTheme.value);
|
|
264
|
+
return this;
|
|
265
|
+
}
|
|
266
|
+
|
|
259
267
|
text(value: string): this {
|
|
260
268
|
this.textValue = value;
|
|
261
269
|
this.clampSelectionToText();
|
|
@@ -461,30 +469,49 @@ export class TextInputCore extends FlexBox {
|
|
|
461
469
|
const resolvedFontSize = this.hasFontSizeOverride ? this.fontSizeOverride : theme.fonts.sizeBody;
|
|
462
470
|
const lineHeight = resolvedFontSize + theme.spacing.sm;
|
|
463
471
|
const editableCursor = this.isEnabled ? CursorStyle.Text : CursorStyle.Default;
|
|
464
|
-
this.presenter.apply(theme, this.createVisualState());
|
|
472
|
+
this.presenter.apply(theme, this.createVisualState(), this.colorsValue);
|
|
465
473
|
|
|
466
474
|
const textVerticalAlign = this.profile.multiline ? TextVerticalAlign.Top : TextVerticalAlign.Center;
|
|
475
|
+
|
|
476
|
+
const colors = this.colorsValue;
|
|
477
|
+
let resolvedTextColor: u32;
|
|
478
|
+
if (this.isEnabled) {
|
|
479
|
+
if (colors !== null && colors.hasTextPrimary) {
|
|
480
|
+
resolvedTextColor = colors.textPrimaryColor;
|
|
481
|
+
} else {
|
|
482
|
+
resolvedTextColor = theme.colors.textPrimary;
|
|
483
|
+
}
|
|
484
|
+
} else {
|
|
485
|
+
if (colors !== null && colors.hasTextMuted) {
|
|
486
|
+
resolvedTextColor = colors.textMutedColor;
|
|
487
|
+
} else {
|
|
488
|
+
resolvedTextColor = theme.colors.textMuted;
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
const resolvedCaretColor = colors !== null && colors.hasCaret ? colors.caretColor : theme.colors.accent;
|
|
492
|
+
|
|
467
493
|
this.editorText
|
|
468
494
|
.width(this.shouldEditorTrackViewportWidth() ? 100.0 : 0.0, this.shouldEditorTrackViewportWidth() ? Unit.Percent : Unit.Auto)
|
|
469
495
|
.height(this.profile.multiline ? 0.0 : lineHeight, this.profile.multiline ? Unit.Auto : Unit.Pixel)
|
|
470
496
|
.fontFamily(resolvedFontFamily)
|
|
471
497
|
.fontSize(resolvedFontSize)
|
|
472
498
|
.verticalAlign(textVerticalAlign)
|
|
473
|
-
.textColor(
|
|
474
|
-
.caretColor(
|
|
499
|
+
.textColor(resolvedTextColor)
|
|
500
|
+
.caretColor(resolvedCaretColor);
|
|
475
501
|
this.syncEditorWrapping();
|
|
476
502
|
|
|
477
503
|
this.placeholderHost
|
|
478
504
|
.width(100.0, Unit.Percent)
|
|
479
505
|
.height(this.profile.multiline ? 0.0 : lineHeight, this.profile.multiline ? Unit.Auto : Unit.Pixel)
|
|
480
506
|
.cursor(editableCursor);
|
|
507
|
+
const resolvedPlaceholderColor = colors !== null && colors.hasPlaceholder ? colors.placeholderColor : theme.colors.textMuted;
|
|
481
508
|
this.placeholderText
|
|
482
509
|
.width(100.0, Unit.Percent)
|
|
483
510
|
.height(this.profile.multiline ? 0.0 : lineHeight, this.profile.multiline ? Unit.Auto : Unit.Pixel)
|
|
484
511
|
.fontFamily(resolvedFontFamily)
|
|
485
512
|
.fontSize(resolvedFontSize)
|
|
486
513
|
.verticalAlign(textVerticalAlign)
|
|
487
|
-
.textColor(
|
|
514
|
+
.textColor(resolvedPlaceholderColor);
|
|
488
515
|
const scrollBox = this.editorScrollBox;
|
|
489
516
|
if (scrollBox !== null) {
|
|
490
517
|
scrollBox.cursor(CursorStyle.Default);
|
|
@@ -492,6 +519,14 @@ export class TextInputCore extends FlexBox {
|
|
|
492
519
|
scrollBox.fillSize();
|
|
493
520
|
this.syncScrollChromeState();
|
|
494
521
|
}
|
|
522
|
+
|
|
523
|
+
if (colors !== null && colors.hasBackground) {
|
|
524
|
+
this.bgColor(colors.backgroundColor);
|
|
525
|
+
}
|
|
526
|
+
if (colors !== null && colors.hasBorder) {
|
|
527
|
+
this.border(1.0, colors.borderColor, BorderStyle.Solid);
|
|
528
|
+
}
|
|
529
|
+
|
|
495
530
|
this.syncFocusChrome(theme);
|
|
496
531
|
}
|
|
497
532
|
|
|
@@ -2,6 +2,7 @@ import { BorderStyle, CursorStyle, Unit } from "../../core/ffi";
|
|
|
2
2
|
import { Node } from "../../core/Node";
|
|
3
3
|
import { Theme } from "../../core/Theme";
|
|
4
4
|
import { FlexBox } from "../../nodes";
|
|
5
|
+
import { TextInputColors } from "../TextInputColors";
|
|
5
6
|
|
|
6
7
|
export class TextInputVisualState {
|
|
7
8
|
constructor(
|
|
@@ -35,7 +36,7 @@ export abstract class TextInputPresenter {
|
|
|
35
36
|
return changetype<FlexBox>(this.placeholderHostValue);
|
|
36
37
|
}
|
|
37
38
|
|
|
38
|
-
abstract apply(theme: Theme, state: TextInputVisualState): void;
|
|
39
|
+
abstract apply(theme: Theme, state: TextInputVisualState, colors?: TextInputColors | null): void;
|
|
39
40
|
}
|
|
40
41
|
|
|
41
42
|
export abstract class TextInputTemplate {
|
|
@@ -43,15 +44,17 @@ export abstract class TextInputTemplate {
|
|
|
43
44
|
}
|
|
44
45
|
|
|
45
46
|
class DefaultTextInputPresenter extends TextInputPresenter {
|
|
46
|
-
apply(theme: Theme, state: TextInputVisualState): void {
|
|
47
|
+
apply(theme: Theme, state: TextInputVisualState, colors: TextInputColors | null = null): void {
|
|
47
48
|
const horizontalPadding = theme.spacing.md;
|
|
48
49
|
const verticalPadding = theme.spacing.sm;
|
|
49
50
|
const editableCursor = state.enabled ? CursorStyle.Text : CursorStyle.Default;
|
|
50
51
|
const shellCursor = !state.multiline && state.enabled ? CursorStyle.Text : CursorStyle.Default;
|
|
52
|
+
const bg = colors !== null && colors.hasBackground ? colors.backgroundColor : theme.colors.surface;
|
|
53
|
+
const borderColor = colors !== null && colors.hasBorder ? colors.borderColor : theme.colors.border;
|
|
51
54
|
this.host
|
|
52
|
-
.bgColor(
|
|
55
|
+
.bgColor(bg)
|
|
53
56
|
.cornerRadius(theme.spacing.sm)
|
|
54
|
-
.border(1.0,
|
|
57
|
+
.border(1.0, borderColor, BorderStyle.Solid)
|
|
55
58
|
.padding(horizontalPadding, verticalPadding, horizontalPadding, verticalPadding)
|
|
56
59
|
.cursor(shellCursor);
|
|
57
60
|
this.host.opacity(state.enabled ? 1.0 : 0.6);
|