@babylonjs/gui 9.15.0 → 9.16.1
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/2D/controls/checkbox.pure.js +164 -153
- package/2D/controls/checkbox.pure.js.map +1 -1
- package/2D/controls/colorpicker.pure.js +1300 -1289
- package/2D/controls/colorpicker.pure.js.map +1 -1
- package/2D/controls/container.pure.js +597 -582
- package/2D/controls/container.pure.js.map +1 -1
- package/2D/controls/control.pure.js +2474 -2434
- package/2D/controls/control.pure.js.map +1 -1
- package/2D/controls/displayGrid.pure.js +201 -190
- package/2D/controls/displayGrid.pure.js.map +1 -1
- package/2D/controls/ellipse.pure.js +96 -85
- package/2D/controls/ellipse.pure.js.map +1 -1
- package/2D/controls/grid.pure.js +511 -500
- package/2D/controls/grid.pure.js.map +1 -1
- package/2D/controls/image.pure.js +888 -877
- package/2D/controls/image.pure.js.map +1 -1
- package/2D/controls/inputText.pure.js +988 -973
- package/2D/controls/inputText.pure.js.map +1 -1
- package/2D/controls/inputTextArea.pure.js +955 -944
- package/2D/controls/inputTextArea.pure.js.map +1 -1
- package/2D/controls/line.pure.js +237 -226
- package/2D/controls/line.pure.js.map +1 -1
- package/2D/controls/multiLine.pure.js +233 -222
- package/2D/controls/multiLine.pure.js.map +1 -1
- package/2D/controls/radioButton.pure.js +182 -169
- package/2D/controls/radioButton.pure.js.map +1 -1
- package/2D/controls/rectangle.pure.js +211 -200
- package/2D/controls/rectangle.pure.js.map +1 -1
- package/2D/controls/scrollViewers/scrollViewer.pure.js +579 -567
- package/2D/controls/scrollViewers/scrollViewer.pure.js.map +1 -1
- package/2D/controls/sliders/baseSlider.js +291 -280
- package/2D/controls/sliders/baseSlider.js.map +1 -1
- package/2D/controls/sliders/imageBasedSlider.pure.js +158 -147
- package/2D/controls/sliders/imageBasedSlider.pure.js.map +1 -1
- package/2D/controls/sliders/imageScrollBar.js +237 -223
- package/2D/controls/sliders/imageScrollBar.js.map +1 -1
- package/2D/controls/sliders/scrollBar.pure.js +169 -158
- package/2D/controls/sliders/scrollBar.pure.js.map +1 -1
- package/2D/controls/sliders/slider.pure.js +251 -240
- package/2D/controls/sliders/slider.pure.js.map +1 -1
- package/2D/controls/stackPanel.pure.js +236 -221
- package/2D/controls/stackPanel.pure.js.map +1 -1
- package/2D/controls/textBlock.pure.js +637 -626
- package/2D/controls/textBlock.pure.js.map +1 -1
- package/3D/materials/fluent/fluentMaterial.pure.d.ts +4 -4
- package/3D/materials/fluent/fluentMaterial.pure.js +322 -273
- package/3D/materials/fluent/fluentMaterial.pure.js.map +1 -1
- package/3D/materials/fluentBackplate/fluentBackplateMaterial.pure.js +510 -454
- package/3D/materials/fluentBackplate/fluentBackplateMaterial.pure.js.map +1 -1
- package/3D/materials/fluentButton/fluentButtonMaterial.pure.js +612 -529
- package/3D/materials/fluentButton/fluentButtonMaterial.pure.js.map +1 -1
- package/3D/materials/mrdl/mrdlBackglowMaterial.pure.js +313 -274
- package/3D/materials/mrdl/mrdlBackglowMaterial.pure.js.map +1 -1
- package/3D/materials/mrdl/mrdlBackplateMaterial.pure.js +462 -405
- package/3D/materials/mrdl/mrdlBackplateMaterial.pure.js.map +1 -1
- package/3D/materials/mrdl/mrdlFrontplateMaterial.pure.js +583 -501
- package/3D/materials/mrdl/mrdlFrontplateMaterial.pure.js.map +1 -1
- package/3D/materials/mrdl/mrdlInnerquadMaterial.pure.js +226 -203
- package/3D/materials/mrdl/mrdlInnerquadMaterial.pure.js.map +1 -1
- package/3D/materials/mrdl/mrdlSliderBarMaterial.pure.js +961 -825
- package/3D/materials/mrdl/mrdlSliderBarMaterial.pure.js.map +1 -1
- package/3D/materials/mrdl/mrdlSliderThumbMaterial.pure.js +961 -825
- package/3D/materials/mrdl/mrdlSliderThumbMaterial.pure.js.map +1 -1
- package/package.json +2 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { __esDecorate, __runInitializers } from "@babylonjs/core/tslib.es6.js";
|
|
2
2
|
import { Observable } from "@babylonjs/core/Misc/observable.js";
|
|
3
3
|
import { ValueAndUnit } from "../valueAndUnit.js";
|
|
4
4
|
import { Control } from "./control.pure.js";
|
|
@@ -34,647 +34,658 @@ export var TextWrapping;
|
|
|
34
34
|
/**
|
|
35
35
|
* Class used to create text block control
|
|
36
36
|
*/
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
let
|
|
329
|
-
|
|
330
|
-
|
|
37
|
+
let TextBlock = (() => {
|
|
38
|
+
var _a;
|
|
39
|
+
let _classSuper = Control;
|
|
40
|
+
let _instanceExtraInitializers = [];
|
|
41
|
+
let _get_resizeToFit_decorators;
|
|
42
|
+
let _get_textWrapping_decorators;
|
|
43
|
+
let _get_text_decorators;
|
|
44
|
+
let _get_textHorizontalAlignment_decorators;
|
|
45
|
+
let _get_textVerticalAlignment_decorators;
|
|
46
|
+
let _set_lineSpacing_decorators;
|
|
47
|
+
let _get_outlineWidth_decorators;
|
|
48
|
+
let _get_underline_decorators;
|
|
49
|
+
let _get_lineThrough_decorators;
|
|
50
|
+
let _get_applyOutlineToUnderline_decorators;
|
|
51
|
+
let _get_outlineColor_decorators;
|
|
52
|
+
let _get_wordDivider_decorators;
|
|
53
|
+
let _get_forceResizeWidth_decorators;
|
|
54
|
+
return _a = class TextBlock extends _classSuper {
|
|
55
|
+
/**
|
|
56
|
+
* Return the line list (you may need to use the onLinesReadyObservable to make sure the list is ready)
|
|
57
|
+
*/
|
|
58
|
+
get lines() {
|
|
59
|
+
return this._lines;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Gets or sets a boolean indicating that the TextBlock will be resized to fit its content
|
|
63
|
+
|
|
64
|
+
*/
|
|
65
|
+
get resizeToFit() {
|
|
66
|
+
return this._resizeToFit;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Gets or sets a boolean indicating that the TextBlock will be resized to fit its content
|
|
70
|
+
|
|
71
|
+
*/
|
|
72
|
+
set resizeToFit(value) {
|
|
73
|
+
if (this._resizeToFit === value) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
this._resizeToFit = value;
|
|
77
|
+
if (this._resizeToFit) {
|
|
78
|
+
this._width.ignoreAdaptiveScaling = true;
|
|
79
|
+
this._height.ignoreAdaptiveScaling = true;
|
|
80
|
+
}
|
|
81
|
+
this._markAsDirty();
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Gets or sets a boolean indicating if text must be wrapped
|
|
85
|
+
*/
|
|
86
|
+
get textWrapping() {
|
|
87
|
+
return this._textWrapping;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Gets or sets a boolean indicating if text must be wrapped
|
|
91
|
+
*/
|
|
92
|
+
set textWrapping(value) {
|
|
93
|
+
if (this._textWrapping === value) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
this._textWrapping = +value;
|
|
97
|
+
this._markAsDirty();
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Gets or sets text to display
|
|
101
|
+
*/
|
|
102
|
+
get text() {
|
|
103
|
+
return this._text;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Gets or sets text to display
|
|
107
|
+
*/
|
|
108
|
+
set text(value) {
|
|
109
|
+
if (this._text === value) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
this._text = value + ""; // Making sure it is a text
|
|
113
|
+
this._markAsDirty();
|
|
114
|
+
this.onTextChangedObservable.notifyObservers(this);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Gets or sets text horizontal alignment (BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_CENTER by default)
|
|
118
|
+
*/
|
|
119
|
+
get textHorizontalAlignment() {
|
|
120
|
+
return this._textHorizontalAlignment;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Gets or sets text horizontal alignment (BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_CENTER by default)
|
|
124
|
+
*/
|
|
125
|
+
set textHorizontalAlignment(value) {
|
|
126
|
+
if (this._textHorizontalAlignment === value) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
this._textHorizontalAlignment = value;
|
|
130
|
+
this._markAsDirty();
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Gets or sets text vertical alignment (BABYLON.GUI.Control.VERTICAL_ALIGNMENT_CENTER by default)
|
|
134
|
+
*/
|
|
135
|
+
get textVerticalAlignment() {
|
|
136
|
+
return this._textVerticalAlignment;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Gets or sets text vertical alignment (BABYLON.GUI.Control.VERTICAL_ALIGNMENT_CENTER by default)
|
|
140
|
+
*/
|
|
141
|
+
set textVerticalAlignment(value) {
|
|
142
|
+
if (this._textVerticalAlignment === value) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
this._textVerticalAlignment = value;
|
|
146
|
+
this._markAsDirty();
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Gets or sets line spacing value
|
|
150
|
+
*/
|
|
151
|
+
set lineSpacing(value) {
|
|
152
|
+
if (this._lineSpacing.fromString(value)) {
|
|
153
|
+
this._markAsDirty();
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Gets or sets line spacing value
|
|
158
|
+
*/
|
|
159
|
+
get lineSpacing() {
|
|
160
|
+
return this._lineSpacing.toString(this._host);
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Gets or sets outlineWidth of the text to display
|
|
164
|
+
*/
|
|
165
|
+
get outlineWidth() {
|
|
166
|
+
return this._outlineWidth;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Gets or sets outlineWidth of the text to display
|
|
170
|
+
*/
|
|
171
|
+
set outlineWidth(value) {
|
|
172
|
+
if (this._outlineWidth === value) {
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
this._outlineWidth = value;
|
|
176
|
+
this._markAsDirty();
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Gets or sets a boolean indicating that text must have underline
|
|
180
|
+
*/
|
|
181
|
+
get underline() {
|
|
182
|
+
return this._underline;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Gets or sets a boolean indicating that text must have underline
|
|
186
|
+
*/
|
|
187
|
+
set underline(value) {
|
|
188
|
+
if (this._underline === value) {
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
this._underline = value;
|
|
192
|
+
this._markAsDirty();
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Gets or sets an boolean indicating that text must be crossed out
|
|
196
|
+
*/
|
|
197
|
+
get lineThrough() {
|
|
198
|
+
return this._lineThrough;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Gets or sets an boolean indicating that text must be crossed out
|
|
202
|
+
*/
|
|
203
|
+
set lineThrough(value) {
|
|
204
|
+
if (this._lineThrough === value) {
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
this._lineThrough = value;
|
|
208
|
+
this._markAsDirty();
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* If the outline should be applied to the underline/strike-through too. Has different behavior in Edge/Chrome vs Firefox.
|
|
212
|
+
*/
|
|
213
|
+
get applyOutlineToUnderline() {
|
|
214
|
+
return this._applyOutlineToUnderline;
|
|
215
|
+
}
|
|
216
|
+
set applyOutlineToUnderline(value) {
|
|
217
|
+
if (this._applyOutlineToUnderline === value) {
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
this._applyOutlineToUnderline = value;
|
|
221
|
+
this._markAsDirty();
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Gets or sets outlineColor of the text to display
|
|
225
|
+
*/
|
|
226
|
+
get outlineColor() {
|
|
227
|
+
return this._outlineColor;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Gets or sets outlineColor of the text to display
|
|
231
|
+
*/
|
|
232
|
+
set outlineColor(value) {
|
|
233
|
+
if (this._outlineColor === value) {
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
this._outlineColor = value;
|
|
237
|
+
this._markAsDirty();
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Gets or sets word divider
|
|
241
|
+
*/
|
|
242
|
+
get wordDivider() {
|
|
243
|
+
return this._wordDivider;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Gets or sets word divider
|
|
247
|
+
*/
|
|
248
|
+
set wordDivider(value) {
|
|
249
|
+
if (this._wordDivider === value) {
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
this._wordDivider = value;
|
|
253
|
+
this._markAsDirty();
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* By default, if a text block has text wrapping other than Clip, its width
|
|
257
|
+
* is not resized even if resizeToFit = true. This parameter forces the width
|
|
258
|
+
* to be resized.
|
|
259
|
+
*/
|
|
260
|
+
get forceResizeWidth() {
|
|
261
|
+
return this._forceResizeWidth;
|
|
262
|
+
}
|
|
263
|
+
set forceResizeWidth(value) {
|
|
264
|
+
if (this._forceResizeWidth === value) {
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
this._forceResizeWidth = value;
|
|
268
|
+
this._markAsDirty();
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Creates a new TextBlock object
|
|
272
|
+
* @param name defines the name of the control
|
|
273
|
+
* @param text defines the text to display (empty string by default)
|
|
274
|
+
*/
|
|
275
|
+
constructor(
|
|
276
|
+
/**
|
|
277
|
+
* Defines the name of the control
|
|
278
|
+
*/
|
|
279
|
+
name, text = "") {
|
|
280
|
+
super(name);
|
|
281
|
+
this.name = (__runInitializers(this, _instanceExtraInitializers), name);
|
|
282
|
+
this._text = "";
|
|
283
|
+
this._textWrapping = 0 /* TextWrapping.Clip */;
|
|
284
|
+
this._textHorizontalAlignment = Control.HORIZONTAL_ALIGNMENT_CENTER;
|
|
285
|
+
this._textVerticalAlignment = Control.VERTICAL_ALIGNMENT_CENTER;
|
|
286
|
+
this._resizeToFit = false;
|
|
287
|
+
this._lineSpacing = new ValueAndUnit(0);
|
|
288
|
+
this._outlineWidth = 0;
|
|
289
|
+
this._outlineColor = "white";
|
|
290
|
+
this._underline = false;
|
|
291
|
+
this._lineThrough = false;
|
|
292
|
+
this._wordDivider = " ";
|
|
293
|
+
this._forceResizeWidth = false;
|
|
294
|
+
this._applyOutlineToUnderline = false;
|
|
295
|
+
/**
|
|
296
|
+
* An event triggered after the text is changed
|
|
297
|
+
*/
|
|
298
|
+
this.onTextChangedObservable = new Observable();
|
|
299
|
+
/**
|
|
300
|
+
* An event triggered after the text was broken up into lines
|
|
301
|
+
*/
|
|
302
|
+
this.onLinesReadyObservable = new Observable();
|
|
303
|
+
/**
|
|
304
|
+
* Gets or sets a boolean indicating if the HTML element generated for word wrapping should be reused or removed after each wrapping.
|
|
305
|
+
*/
|
|
306
|
+
this.reuseHTMLForWordWrapping = false;
|
|
307
|
+
this._linesTemp = [];
|
|
308
|
+
this._htmlElement = null;
|
|
309
|
+
this.text = text;
|
|
310
|
+
}
|
|
311
|
+
_getTypeName() {
|
|
312
|
+
return "TextBlock";
|
|
313
|
+
}
|
|
314
|
+
_processMeasures(parentMeasure, context) {
|
|
315
|
+
super._processMeasures(parentMeasure, context);
|
|
316
|
+
// Apply states so we can use the right font to measure
|
|
317
|
+
context.save();
|
|
318
|
+
this._applyStates(context);
|
|
319
|
+
// Measure the font
|
|
320
|
+
if (!this._fontOffset || this.isDirty) {
|
|
321
|
+
this._fontOffset = Control._GetFontOffset(context.font, this._host.getScene()?.getEngine());
|
|
322
|
+
}
|
|
323
|
+
// Prepare lines
|
|
324
|
+
this._lines = this._breakLines(this._currentMeasure.width, this._currentMeasure.height, context);
|
|
325
|
+
this.onLinesReadyObservable.notifyObservers(this);
|
|
326
|
+
// Restore context now that we're done measuring the font
|
|
327
|
+
context.restore();
|
|
328
|
+
let maxLineWidth = 0;
|
|
329
|
+
for (let i = 0; i < this._lines.length; i++) {
|
|
330
|
+
const line = this._lines[i];
|
|
331
|
+
if (line.width > maxLineWidth) {
|
|
332
|
+
maxLineWidth = line.width;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
if (this._resizeToFit) {
|
|
336
|
+
if (this._textWrapping === 0 /* TextWrapping.Clip */ || this._forceResizeWidth) {
|
|
337
|
+
const newWidth = Math.ceil(this._paddingLeftInPixels) + Math.ceil(this._paddingRightInPixels) + Math.ceil(maxLineWidth);
|
|
338
|
+
if (newWidth !== this._width.getValueInPixel(this._host, this._tempParentMeasure.width)) {
|
|
339
|
+
this._width.updateInPlace(newWidth, ValueAndUnit.UNITMODE_PIXEL);
|
|
340
|
+
this._rebuildLayout = true;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
let newHeight = (this._paddingTopInPixels + this._paddingBottomInPixels + this._fontOffset.height * this._lines.length) | 0;
|
|
344
|
+
if (this._lines.length > 0 && this._lineSpacing.internalValue !== 0) {
|
|
345
|
+
let lineSpacing;
|
|
346
|
+
if (this._lineSpacing.isPixel) {
|
|
347
|
+
lineSpacing = this._lineSpacing.getValue(this._host);
|
|
348
|
+
}
|
|
349
|
+
else {
|
|
350
|
+
lineSpacing = this._lineSpacing.getValue(this._host) * this._height.getValueInPixel(this._host, this._cachedParentMeasure.height);
|
|
351
|
+
}
|
|
352
|
+
newHeight += (this._lines.length - 1) * lineSpacing;
|
|
353
|
+
}
|
|
354
|
+
if (newHeight !== this._height.internalValue) {
|
|
355
|
+
this._height.updateInPlace(newHeight, ValueAndUnit.UNITMODE_PIXEL);
|
|
356
|
+
this._rebuildLayout = true;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
_drawText(text, textWidth, y, context) {
|
|
361
|
+
const width = this._currentMeasure.width;
|
|
362
|
+
let x = 0;
|
|
363
|
+
switch (this._textHorizontalAlignment) {
|
|
364
|
+
case Control.HORIZONTAL_ALIGNMENT_LEFT:
|
|
365
|
+
x = 0;
|
|
366
|
+
break;
|
|
367
|
+
case Control.HORIZONTAL_ALIGNMENT_RIGHT:
|
|
368
|
+
x = width - textWidth;
|
|
369
|
+
break;
|
|
370
|
+
case Control.HORIZONTAL_ALIGNMENT_CENTER:
|
|
371
|
+
x = (width - textWidth) / 2;
|
|
372
|
+
break;
|
|
373
|
+
}
|
|
374
|
+
if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
|
|
375
|
+
context.shadowColor = this.shadowColor;
|
|
376
|
+
context.shadowBlur = this.shadowBlur;
|
|
377
|
+
const idealRatio = this.host.idealRatio;
|
|
378
|
+
context.shadowOffsetX = this.shadowOffsetX * idealRatio;
|
|
379
|
+
context.shadowOffsetY = this.shadowOffsetY * idealRatio;
|
|
380
|
+
}
|
|
381
|
+
if (this.outlineWidth) {
|
|
382
|
+
context.strokeText(text, this._currentMeasure.left + x, y);
|
|
383
|
+
}
|
|
384
|
+
context.fillText(text, this._currentMeasure.left + x, y);
|
|
385
|
+
if (this._underline) {
|
|
386
|
+
this._drawLine(this._currentMeasure.left + x, y + 3, this._currentMeasure.left + x + textWidth, y + 3, context);
|
|
387
|
+
}
|
|
388
|
+
if (this._lineThrough) {
|
|
389
|
+
this._drawLine(this._currentMeasure.left + x, y - this.fontSizeInPixels / 3, this._currentMeasure.left + x + textWidth, y - this.fontSizeInPixels / 3, context);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
_drawLine(xFrom, yFrom, xTo, yTo, context) {
|
|
393
|
+
context.beginPath();
|
|
394
|
+
context.lineWidth = Math.round(this.fontSizeInPixels * 0.05);
|
|
395
|
+
context.moveTo(xFrom, yFrom);
|
|
396
|
+
context.lineTo(xTo, yTo);
|
|
397
|
+
if (this.outlineWidth && this.applyOutlineToUnderline) {
|
|
398
|
+
context.stroke();
|
|
399
|
+
context.fill();
|
|
331
400
|
}
|
|
332
401
|
else {
|
|
333
|
-
|
|
402
|
+
const currentStroke = context.strokeStyle;
|
|
403
|
+
context.strokeStyle = context.fillStyle;
|
|
404
|
+
context.stroke();
|
|
405
|
+
context.strokeStyle = currentStroke;
|
|
334
406
|
}
|
|
335
|
-
|
|
407
|
+
context.closePath();
|
|
336
408
|
}
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
409
|
+
/**
|
|
410
|
+
* @internal
|
|
411
|
+
*/
|
|
412
|
+
_draw(context) {
|
|
413
|
+
context.save();
|
|
414
|
+
this._applyStates(context);
|
|
415
|
+
// Render lines
|
|
416
|
+
this._renderLines(context);
|
|
417
|
+
context.restore();
|
|
340
418
|
}
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
break;
|
|
350
|
-
case Control.HORIZONTAL_ALIGNMENT_RIGHT:
|
|
351
|
-
x = width - textWidth;
|
|
352
|
-
break;
|
|
353
|
-
case Control.HORIZONTAL_ALIGNMENT_CENTER:
|
|
354
|
-
x = (width - textWidth) / 2;
|
|
355
|
-
break;
|
|
356
|
-
}
|
|
357
|
-
if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
|
|
358
|
-
context.shadowColor = this.shadowColor;
|
|
359
|
-
context.shadowBlur = this.shadowBlur;
|
|
360
|
-
const idealRatio = this.host.idealRatio;
|
|
361
|
-
context.shadowOffsetX = this.shadowOffsetX * idealRatio;
|
|
362
|
-
context.shadowOffsetY = this.shadowOffsetY * idealRatio;
|
|
363
|
-
}
|
|
364
|
-
if (this.outlineWidth) {
|
|
365
|
-
context.strokeText(text, this._currentMeasure.left + x, y);
|
|
366
|
-
}
|
|
367
|
-
context.fillText(text, this._currentMeasure.left + x, y);
|
|
368
|
-
if (this._underline) {
|
|
369
|
-
this._drawLine(this._currentMeasure.left + x, y + 3, this._currentMeasure.left + x + textWidth, y + 3, context);
|
|
370
|
-
}
|
|
371
|
-
if (this._lineThrough) {
|
|
372
|
-
this._drawLine(this._currentMeasure.left + x, y - this.fontSizeInPixels / 3, this._currentMeasure.left + x + textWidth, y - this.fontSizeInPixels / 3, context);
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
_drawLine(xFrom, yFrom, xTo, yTo, context) {
|
|
376
|
-
context.beginPath();
|
|
377
|
-
context.lineWidth = Math.round(this.fontSizeInPixels * 0.05);
|
|
378
|
-
context.moveTo(xFrom, yFrom);
|
|
379
|
-
context.lineTo(xTo, yTo);
|
|
380
|
-
if (this.outlineWidth && this.applyOutlineToUnderline) {
|
|
381
|
-
context.stroke();
|
|
382
|
-
context.fill();
|
|
383
|
-
}
|
|
384
|
-
else {
|
|
385
|
-
const currentStroke = context.strokeStyle;
|
|
386
|
-
context.strokeStyle = context.fillStyle;
|
|
387
|
-
context.stroke();
|
|
388
|
-
context.strokeStyle = currentStroke;
|
|
389
|
-
}
|
|
390
|
-
context.closePath();
|
|
391
|
-
}
|
|
392
|
-
/**
|
|
393
|
-
* @internal
|
|
394
|
-
*/
|
|
395
|
-
_draw(context) {
|
|
396
|
-
context.save();
|
|
397
|
-
this._applyStates(context);
|
|
398
|
-
// Render lines
|
|
399
|
-
this._renderLines(context);
|
|
400
|
-
context.restore();
|
|
401
|
-
}
|
|
402
|
-
_applyStates(context) {
|
|
403
|
-
super._applyStates(context);
|
|
404
|
-
if (this.outlineWidth) {
|
|
405
|
-
context.lineWidth = this.outlineWidth;
|
|
406
|
-
context.strokeStyle = this.outlineColor;
|
|
407
|
-
context.lineJoin = "miter";
|
|
408
|
-
context.miterLimit = 2;
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
_breakLines(refWidth, refHeight, context) {
|
|
412
|
-
this._linesTemp.length = 0;
|
|
413
|
-
const _lines = this._textWrapping === 4 /* TextWrapping.HTML */ ? this._parseHTMLText(refWidth, refHeight, context) : this.text.split("\n");
|
|
414
|
-
switch (this._textWrapping) {
|
|
415
|
-
case 1 /* TextWrapping.WordWrap */:
|
|
416
|
-
for (const _line of _lines) {
|
|
417
|
-
this._linesTemp.push(...this._parseLineWordWrap(_line, refWidth, context));
|
|
418
|
-
}
|
|
419
|
-
break;
|
|
420
|
-
case 2 /* TextWrapping.Ellipsis */:
|
|
421
|
-
for (const _line of _lines) {
|
|
422
|
-
this._linesTemp.push(this._parseLineEllipsis(_line, refWidth, context));
|
|
423
|
-
}
|
|
424
|
-
break;
|
|
425
|
-
case 3 /* TextWrapping.WordWrapEllipsis */:
|
|
426
|
-
for (const _line of _lines) {
|
|
427
|
-
this._linesTemp.push(...this._parseLineWordWrapEllipsis(_line, refWidth, refHeight, context));
|
|
428
|
-
}
|
|
429
|
-
break;
|
|
430
|
-
case 4 /* TextWrapping.HTML */:
|
|
431
|
-
default:
|
|
432
|
-
for (const _line of _lines) {
|
|
433
|
-
this._linesTemp.push(this._parseLine(_line, context));
|
|
434
|
-
}
|
|
435
|
-
break;
|
|
436
|
-
}
|
|
437
|
-
return this._linesTemp;
|
|
438
|
-
}
|
|
439
|
-
_parseHTMLText(refWidth, refHeight, context) {
|
|
440
|
-
const lines = [];
|
|
441
|
-
if (!this._htmlElement) {
|
|
442
|
-
this._htmlElement = document.createElement("div");
|
|
443
|
-
document.body.appendChild(this._htmlElement);
|
|
444
|
-
}
|
|
445
|
-
const htmlElement = this._htmlElement;
|
|
446
|
-
htmlElement.textContent = this.text;
|
|
447
|
-
htmlElement.style.font = context.font;
|
|
448
|
-
htmlElement.style.position = "absolute";
|
|
449
|
-
htmlElement.style.visibility = "hidden";
|
|
450
|
-
htmlElement.style.top = "-1000px";
|
|
451
|
-
htmlElement.style.left = "-1000px";
|
|
452
|
-
this.adjustWordWrappingHTMLElement?.(htmlElement);
|
|
453
|
-
htmlElement.style.width = refWidth + "px";
|
|
454
|
-
htmlElement.style.height = refHeight + "px";
|
|
455
|
-
const textContent = htmlElement.textContent;
|
|
456
|
-
if (!textContent) {
|
|
457
|
-
return lines;
|
|
458
|
-
}
|
|
459
|
-
// get the text node
|
|
460
|
-
const textNode = htmlElement.childNodes[0];
|
|
461
|
-
const range = document.createRange();
|
|
462
|
-
let idx = 0;
|
|
463
|
-
for (const c of textContent) {
|
|
464
|
-
range.setStart(textNode, 0);
|
|
465
|
-
range.setEnd(textNode, idx + 1);
|
|
466
|
-
// "select" text from beginning to this position to determine the line
|
|
467
|
-
const lineIndex = range.getClientRects().length - 1;
|
|
468
|
-
lines[lineIndex] = (lines[lineIndex] || "") + c;
|
|
469
|
-
idx++;
|
|
470
|
-
}
|
|
471
|
-
if (!this.reuseHTMLForWordWrapping) {
|
|
472
|
-
htmlElement.remove();
|
|
473
|
-
this._htmlElement = null;
|
|
474
|
-
}
|
|
475
|
-
return lines;
|
|
476
|
-
}
|
|
477
|
-
_parseLine(line = "", context) {
|
|
478
|
-
return { text: line, width: this._getTextMetricsWidth(context.measureText(line)) };
|
|
479
|
-
}
|
|
480
|
-
//Calculate how many characters approximately we need to remove
|
|
481
|
-
_getCharsToRemove(lineWidth, width, lineLength) {
|
|
482
|
-
const diff = lineWidth > width ? lineWidth - width : 0;
|
|
483
|
-
// This isn't exact unless the font is monospaced
|
|
484
|
-
const charWidth = lineWidth / lineLength;
|
|
485
|
-
const removeChars = Math.max(Math.floor(diff / charWidth), 1);
|
|
486
|
-
return removeChars;
|
|
487
|
-
}
|
|
488
|
-
_parseLineEllipsis(line = "", width, context) {
|
|
489
|
-
let lineWidth = this._getTextMetricsWidth(context.measureText(line));
|
|
490
|
-
let removeChars = this._getCharsToRemove(lineWidth, width, line.length);
|
|
491
|
-
// unicode support. split('') does not work with unicode!
|
|
492
|
-
// make sure Array.from is available
|
|
493
|
-
const characters = Array.from && Array.from(line);
|
|
494
|
-
if (!characters) {
|
|
495
|
-
// no array.from, use the old method
|
|
496
|
-
while (line.length > 2 && lineWidth > width) {
|
|
497
|
-
line = line.slice(0, -removeChars);
|
|
498
|
-
lineWidth = this._getTextMetricsWidth(context.measureText(line + "…"));
|
|
499
|
-
removeChars = this._getCharsToRemove(lineWidth, width, line.length);
|
|
500
|
-
}
|
|
501
|
-
// Add on the end
|
|
502
|
-
line += "…";
|
|
503
|
-
}
|
|
504
|
-
else {
|
|
505
|
-
while (characters.length && lineWidth > width) {
|
|
506
|
-
characters.splice(characters.length - removeChars, removeChars);
|
|
507
|
-
line = `${characters.join("")}…`;
|
|
508
|
-
lineWidth = this._getTextMetricsWidth(context.measureText(line));
|
|
509
|
-
removeChars = this._getCharsToRemove(lineWidth, width, line.length);
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
return { text: line, width: lineWidth };
|
|
513
|
-
}
|
|
514
|
-
_getTextMetricsWidth(textMetrics) {
|
|
515
|
-
if (textMetrics.actualBoundingBoxLeft !== undefined) {
|
|
516
|
-
return Math.abs(textMetrics.actualBoundingBoxLeft) + Math.abs(textMetrics.actualBoundingBoxRight);
|
|
517
|
-
}
|
|
518
|
-
return textMetrics.width;
|
|
519
|
-
}
|
|
520
|
-
_parseLineWordWrap(line = "", width, context) {
|
|
521
|
-
const lines = [];
|
|
522
|
-
const words = this.wordSplittingFunction ? this.wordSplittingFunction(line) : line.split(this._wordDivider);
|
|
523
|
-
let lineWidth = this._getTextMetricsWidth(context.measureText(line));
|
|
524
|
-
for (let n = 0; n < words.length; n++) {
|
|
525
|
-
const testLine = n > 0 ? line + this._wordDivider + words[n] : words[0];
|
|
526
|
-
const testWidth = this._getTextMetricsWidth(context.measureText(testLine));
|
|
527
|
-
if (testWidth > width && n > 0) {
|
|
528
|
-
lines.push({ text: line, width: lineWidth });
|
|
529
|
-
line = words[n];
|
|
530
|
-
lineWidth = this._getTextMetricsWidth(context.measureText(line));
|
|
419
|
+
_applyStates(context) {
|
|
420
|
+
super._applyStates(context);
|
|
421
|
+
if (this.outlineWidth) {
|
|
422
|
+
context.lineWidth = this.outlineWidth;
|
|
423
|
+
context.strokeStyle = this.outlineColor;
|
|
424
|
+
context.lineJoin = "miter";
|
|
425
|
+
context.miterLimit = 2;
|
|
426
|
+
}
|
|
531
427
|
}
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
428
|
+
_breakLines(refWidth, refHeight, context) {
|
|
429
|
+
this._linesTemp.length = 0;
|
|
430
|
+
const _lines = this._textWrapping === 4 /* TextWrapping.HTML */ ? this._parseHTMLText(refWidth, refHeight, context) : this.text.split("\n");
|
|
431
|
+
switch (this._textWrapping) {
|
|
432
|
+
case 1 /* TextWrapping.WordWrap */:
|
|
433
|
+
for (const _line of _lines) {
|
|
434
|
+
this._linesTemp.push(...this._parseLineWordWrap(_line, refWidth, context));
|
|
435
|
+
}
|
|
436
|
+
break;
|
|
437
|
+
case 2 /* TextWrapping.Ellipsis */:
|
|
438
|
+
for (const _line of _lines) {
|
|
439
|
+
this._linesTemp.push(this._parseLineEllipsis(_line, refWidth, context));
|
|
440
|
+
}
|
|
441
|
+
break;
|
|
442
|
+
case 3 /* TextWrapping.WordWrapEllipsis */:
|
|
443
|
+
for (const _line of _lines) {
|
|
444
|
+
this._linesTemp.push(...this._parseLineWordWrapEllipsis(_line, refWidth, refHeight, context));
|
|
445
|
+
}
|
|
446
|
+
break;
|
|
447
|
+
case 4 /* TextWrapping.HTML */:
|
|
448
|
+
default:
|
|
449
|
+
for (const _line of _lines) {
|
|
450
|
+
this._linesTemp.push(this._parseLine(_line, context));
|
|
451
|
+
}
|
|
452
|
+
break;
|
|
453
|
+
}
|
|
454
|
+
return this._linesTemp;
|
|
535
455
|
}
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
456
|
+
_parseHTMLText(refWidth, refHeight, context) {
|
|
457
|
+
const lines = [];
|
|
458
|
+
if (!this._htmlElement) {
|
|
459
|
+
this._htmlElement = document.createElement("div");
|
|
460
|
+
document.body.appendChild(this._htmlElement);
|
|
461
|
+
}
|
|
462
|
+
const htmlElement = this._htmlElement;
|
|
463
|
+
htmlElement.textContent = this.text;
|
|
464
|
+
htmlElement.style.font = context.font;
|
|
465
|
+
htmlElement.style.position = "absolute";
|
|
466
|
+
htmlElement.style.visibility = "hidden";
|
|
467
|
+
htmlElement.style.top = "-1000px";
|
|
468
|
+
htmlElement.style.left = "-1000px";
|
|
469
|
+
this.adjustWordWrappingHTMLElement?.(htmlElement);
|
|
470
|
+
htmlElement.style.width = refWidth + "px";
|
|
471
|
+
htmlElement.style.height = refHeight + "px";
|
|
472
|
+
const textContent = htmlElement.textContent;
|
|
473
|
+
if (!textContent) {
|
|
474
|
+
return lines;
|
|
475
|
+
}
|
|
476
|
+
// get the text node
|
|
477
|
+
const textNode = htmlElement.childNodes[0];
|
|
478
|
+
const range = document.createRange();
|
|
479
|
+
let idx = 0;
|
|
480
|
+
for (const c of textContent) {
|
|
481
|
+
range.setStart(textNode, 0);
|
|
482
|
+
range.setEnd(textNode, idx + 1);
|
|
483
|
+
// "select" text from beginning to this position to determine the line
|
|
484
|
+
const lineIndex = range.getClientRects().length - 1;
|
|
485
|
+
lines[lineIndex] = (lines[lineIndex] || "") + c;
|
|
486
|
+
idx++;
|
|
487
|
+
}
|
|
488
|
+
if (!this.reuseHTMLForWordWrapping) {
|
|
489
|
+
htmlElement.remove();
|
|
490
|
+
this._htmlElement = null;
|
|
551
491
|
}
|
|
552
492
|
return lines;
|
|
553
493
|
}
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
494
|
+
_parseLine(line = "", context) {
|
|
495
|
+
return { text: line, width: this._getTextMetricsWidth(context.measureText(line)) };
|
|
496
|
+
}
|
|
497
|
+
//Calculate how many characters approximately we need to remove
|
|
498
|
+
_getCharsToRemove(lineWidth, width, lineLength) {
|
|
499
|
+
const diff = lineWidth > width ? lineWidth - width : 0;
|
|
500
|
+
// This isn't exact unless the font is monospaced
|
|
501
|
+
const charWidth = lineWidth / lineLength;
|
|
502
|
+
const removeChars = Math.max(Math.floor(diff / charWidth), 1);
|
|
503
|
+
return removeChars;
|
|
504
|
+
}
|
|
505
|
+
_parseLineEllipsis(line = "", width, context) {
|
|
506
|
+
let lineWidth = this._getTextMetricsWidth(context.measureText(line));
|
|
507
|
+
let removeChars = this._getCharsToRemove(lineWidth, width, line.length);
|
|
508
|
+
// unicode support. split('') does not work with unicode!
|
|
509
|
+
// make sure Array.from is available
|
|
510
|
+
const characters = Array.from && Array.from(line);
|
|
511
|
+
if (!characters) {
|
|
512
|
+
// no array.from, use the old method
|
|
513
|
+
while (line.length > 2 && lineWidth > width) {
|
|
514
|
+
line = line.slice(0, -removeChars);
|
|
515
|
+
lineWidth = this._getTextMetricsWidth(context.measureText(line + "…"));
|
|
516
|
+
removeChars = this._getCharsToRemove(lineWidth, width, line.length);
|
|
517
|
+
}
|
|
518
|
+
// Add on the end
|
|
519
|
+
line += "…";
|
|
580
520
|
}
|
|
581
521
|
else {
|
|
582
|
-
|
|
522
|
+
while (characters.length && lineWidth > width) {
|
|
523
|
+
characters.splice(characters.length - removeChars, removeChars);
|
|
524
|
+
line = `${characters.join("")}…`;
|
|
525
|
+
lineWidth = this._getTextMetricsWidth(context.measureText(line));
|
|
526
|
+
removeChars = this._getCharsToRemove(lineWidth, width, line.length);
|
|
527
|
+
}
|
|
583
528
|
}
|
|
529
|
+
return { text: line, width: lineWidth };
|
|
584
530
|
}
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
}
|
|
589
|
-
_computeHeightForLinesOf(lineCount) {
|
|
590
|
-
let newHeight = this._paddingTopInPixels + this._paddingBottomInPixels + this._fontOffset.height * lineCount;
|
|
591
|
-
if (lineCount > 0 && this._lineSpacing.internalValue !== 0) {
|
|
592
|
-
let lineSpacing;
|
|
593
|
-
if (this._lineSpacing.isPixel) {
|
|
594
|
-
lineSpacing = this._lineSpacing.getValue(this._host);
|
|
595
|
-
}
|
|
596
|
-
else {
|
|
597
|
-
lineSpacing = this._lineSpacing.getValue(this._host) * this._height.getValueInPixel(this._host, this._cachedParentMeasure.height);
|
|
598
|
-
}
|
|
599
|
-
newHeight += (lineCount - 1) * lineSpacing;
|
|
600
|
-
}
|
|
601
|
-
return newHeight;
|
|
602
|
-
}
|
|
603
|
-
isDimensionFullyDefined(dim) {
|
|
604
|
-
if (this.resizeToFit) {
|
|
605
|
-
return true;
|
|
606
|
-
}
|
|
607
|
-
return super.isDimensionFullyDefined(dim);
|
|
608
|
-
}
|
|
609
|
-
/**
|
|
610
|
-
* Given a width constraint applied on the text block, find the expected height
|
|
611
|
-
* @returns expected height
|
|
612
|
-
*/
|
|
613
|
-
computeExpectedHeight() {
|
|
614
|
-
if (this.text && this.widthInPixels) {
|
|
615
|
-
// Should abstract platform instead of using LastCreatedEngine
|
|
616
|
-
const context = EngineStore.LastCreatedEngine?.createCanvas(0, 0).getContext("2d");
|
|
617
|
-
if (context) {
|
|
618
|
-
// This is a temporary context, no need to save/restore
|
|
619
|
-
// eslint-disable-next-line babylonjs/require-context-save-before-apply-states
|
|
620
|
-
this._applyStates(context);
|
|
621
|
-
if (!this._fontOffset) {
|
|
622
|
-
this._fontOffset = Control._GetFontOffset(context.font, this._host.getScene()?.getEngine());
|
|
531
|
+
_getTextMetricsWidth(textMetrics) {
|
|
532
|
+
if (textMetrics.actualBoundingBoxLeft !== undefined) {
|
|
533
|
+
return Math.abs(textMetrics.actualBoundingBoxLeft) + Math.abs(textMetrics.actualBoundingBoxRight);
|
|
623
534
|
}
|
|
624
|
-
|
|
625
|
-
? this._lines
|
|
626
|
-
: this._breakLines(this.widthInPixels - this._paddingLeftInPixels - this._paddingRightInPixels, this.heightInPixels - this._paddingTopInPixels - this._paddingBottomInPixels, context);
|
|
627
|
-
return this._computeHeightForLinesOf(lines.length);
|
|
535
|
+
return textMetrics.width;
|
|
628
536
|
}
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
]
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
537
|
+
_parseLineWordWrap(line = "", width, context) {
|
|
538
|
+
const lines = [];
|
|
539
|
+
const words = this.wordSplittingFunction ? this.wordSplittingFunction(line) : line.split(this._wordDivider);
|
|
540
|
+
let lineWidth = this._getTextMetricsWidth(context.measureText(line));
|
|
541
|
+
for (let n = 0; n < words.length; n++) {
|
|
542
|
+
const testLine = n > 0 ? line + this._wordDivider + words[n] : words[0];
|
|
543
|
+
const testWidth = this._getTextMetricsWidth(context.measureText(testLine));
|
|
544
|
+
if (testWidth > width && n > 0) {
|
|
545
|
+
lines.push({ text: line, width: lineWidth });
|
|
546
|
+
line = words[n];
|
|
547
|
+
lineWidth = this._getTextMetricsWidth(context.measureText(line));
|
|
548
|
+
}
|
|
549
|
+
else {
|
|
550
|
+
lineWidth = testWidth;
|
|
551
|
+
line = testLine;
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
lines.push({ text: line, width: lineWidth });
|
|
555
|
+
return lines;
|
|
556
|
+
}
|
|
557
|
+
_parseLineWordWrapEllipsis(line = "", width, height, context) {
|
|
558
|
+
const lines = this._parseLineWordWrap(line, width, context);
|
|
559
|
+
for (let n = 1; n <= lines.length; n++) {
|
|
560
|
+
const currentHeight = this._computeHeightForLinesOf(n);
|
|
561
|
+
if (currentHeight > height && n > 1) {
|
|
562
|
+
const lastLine = lines[n - 2];
|
|
563
|
+
const currentLine = lines[n - 1];
|
|
564
|
+
lines[n - 2] = this._parseLineEllipsis(lastLine.text + this._wordDivider + currentLine.text, width, context);
|
|
565
|
+
const linesToRemove = lines.length - n + 1;
|
|
566
|
+
for (let i = 0; i < linesToRemove; i++) {
|
|
567
|
+
lines.pop();
|
|
568
|
+
}
|
|
569
|
+
return lines;
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
return lines;
|
|
573
|
+
}
|
|
574
|
+
_renderLines(context) {
|
|
575
|
+
if (!this._fontOffset || !this._lines) {
|
|
576
|
+
return;
|
|
577
|
+
}
|
|
578
|
+
const height = this._currentMeasure.height;
|
|
579
|
+
let rootY = 0;
|
|
580
|
+
switch (this._textVerticalAlignment) {
|
|
581
|
+
case Control.VERTICAL_ALIGNMENT_TOP:
|
|
582
|
+
rootY = this._fontOffset.ascent;
|
|
583
|
+
break;
|
|
584
|
+
case Control.VERTICAL_ALIGNMENT_BOTTOM:
|
|
585
|
+
rootY = height - this._fontOffset.height * (this._lines.length - 1) - this._fontOffset.descent;
|
|
586
|
+
break;
|
|
587
|
+
case Control.VERTICAL_ALIGNMENT_CENTER:
|
|
588
|
+
rootY = this._fontOffset.ascent + (height - this._fontOffset.height * this._lines.length) / 2;
|
|
589
|
+
break;
|
|
590
|
+
}
|
|
591
|
+
rootY += this._currentMeasure.top;
|
|
592
|
+
for (let i = 0; i < this._lines.length; i++) {
|
|
593
|
+
const line = this._lines[i];
|
|
594
|
+
if (i !== 0 && this._lineSpacing.internalValue !== 0) {
|
|
595
|
+
if (this._lineSpacing.isPixel) {
|
|
596
|
+
rootY += this._lineSpacing.getValue(this._host);
|
|
597
|
+
}
|
|
598
|
+
else {
|
|
599
|
+
rootY = rootY + this._lineSpacing.getValue(this._host) * this._height.getValueInPixel(this._host, this._cachedParentMeasure.height);
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
this._drawText(line.text, line.width, rootY, context);
|
|
603
|
+
rootY += this._fontOffset.height;
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
_computeHeightForLinesOf(lineCount) {
|
|
607
|
+
let newHeight = this._paddingTopInPixels + this._paddingBottomInPixels + this._fontOffset.height * lineCount;
|
|
608
|
+
if (lineCount > 0 && this._lineSpacing.internalValue !== 0) {
|
|
609
|
+
let lineSpacing;
|
|
610
|
+
if (this._lineSpacing.isPixel) {
|
|
611
|
+
lineSpacing = this._lineSpacing.getValue(this._host);
|
|
612
|
+
}
|
|
613
|
+
else {
|
|
614
|
+
lineSpacing = this._lineSpacing.getValue(this._host) * this._height.getValueInPixel(this._host, this._cachedParentMeasure.height);
|
|
615
|
+
}
|
|
616
|
+
newHeight += (lineCount - 1) * lineSpacing;
|
|
617
|
+
}
|
|
618
|
+
return newHeight;
|
|
619
|
+
}
|
|
620
|
+
isDimensionFullyDefined(dim) {
|
|
621
|
+
if (this.resizeToFit) {
|
|
622
|
+
return true;
|
|
623
|
+
}
|
|
624
|
+
return super.isDimensionFullyDefined(dim);
|
|
625
|
+
}
|
|
626
|
+
/**
|
|
627
|
+
* Given a width constraint applied on the text block, find the expected height
|
|
628
|
+
* @returns expected height
|
|
629
|
+
*/
|
|
630
|
+
computeExpectedHeight() {
|
|
631
|
+
if (this.text && this.widthInPixels) {
|
|
632
|
+
// Should abstract platform instead of using LastCreatedEngine
|
|
633
|
+
const context = EngineStore.LastCreatedEngine?.createCanvas(0, 0).getContext("2d");
|
|
634
|
+
if (context) {
|
|
635
|
+
// This is a temporary context, no need to save/restore
|
|
636
|
+
// eslint-disable-next-line babylonjs/require-context-save-before-apply-states
|
|
637
|
+
this._applyStates(context);
|
|
638
|
+
if (!this._fontOffset) {
|
|
639
|
+
this._fontOffset = Control._GetFontOffset(context.font, this._host.getScene()?.getEngine());
|
|
640
|
+
}
|
|
641
|
+
const lines = this._lines
|
|
642
|
+
? this._lines
|
|
643
|
+
: this._breakLines(this.widthInPixels - this._paddingLeftInPixels - this._paddingRightInPixels, this.heightInPixels - this._paddingTopInPixels - this._paddingBottomInPixels, context);
|
|
644
|
+
return this._computeHeightForLinesOf(lines.length);
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
return 0;
|
|
648
|
+
}
|
|
649
|
+
dispose() {
|
|
650
|
+
super.dispose();
|
|
651
|
+
this.onTextChangedObservable.clear();
|
|
652
|
+
this._htmlElement?.remove();
|
|
653
|
+
this._htmlElement = null;
|
|
654
|
+
}
|
|
655
|
+
},
|
|
656
|
+
(() => {
|
|
657
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
658
|
+
_get_resizeToFit_decorators = [serialize()];
|
|
659
|
+
_get_textWrapping_decorators = [serialize()];
|
|
660
|
+
_get_text_decorators = [serialize()];
|
|
661
|
+
_get_textHorizontalAlignment_decorators = [serialize()];
|
|
662
|
+
_get_textVerticalAlignment_decorators = [serialize()];
|
|
663
|
+
_set_lineSpacing_decorators = [serialize()];
|
|
664
|
+
_get_outlineWidth_decorators = [serialize()];
|
|
665
|
+
_get_underline_decorators = [serialize()];
|
|
666
|
+
_get_lineThrough_decorators = [serialize()];
|
|
667
|
+
_get_applyOutlineToUnderline_decorators = [serialize()];
|
|
668
|
+
_get_outlineColor_decorators = [serialize()];
|
|
669
|
+
_get_wordDivider_decorators = [serialize()];
|
|
670
|
+
_get_forceResizeWidth_decorators = [serialize()];
|
|
671
|
+
__esDecorate(_a, null, _get_resizeToFit_decorators, { kind: "getter", name: "resizeToFit", static: false, private: false, access: { has: obj => "resizeToFit" in obj, get: obj => obj.resizeToFit }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
672
|
+
__esDecorate(_a, null, _get_textWrapping_decorators, { kind: "getter", name: "textWrapping", static: false, private: false, access: { has: obj => "textWrapping" in obj, get: obj => obj.textWrapping }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
673
|
+
__esDecorate(_a, null, _get_text_decorators, { kind: "getter", name: "text", static: false, private: false, access: { has: obj => "text" in obj, get: obj => obj.text }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
674
|
+
__esDecorate(_a, null, _get_textHorizontalAlignment_decorators, { kind: "getter", name: "textHorizontalAlignment", static: false, private: false, access: { has: obj => "textHorizontalAlignment" in obj, get: obj => obj.textHorizontalAlignment }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
675
|
+
__esDecorate(_a, null, _get_textVerticalAlignment_decorators, { kind: "getter", name: "textVerticalAlignment", static: false, private: false, access: { has: obj => "textVerticalAlignment" in obj, get: obj => obj.textVerticalAlignment }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
676
|
+
__esDecorate(_a, null, _set_lineSpacing_decorators, { kind: "setter", name: "lineSpacing", static: false, private: false, access: { has: obj => "lineSpacing" in obj, set: (obj, value) => { obj.lineSpacing = value; } }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
677
|
+
__esDecorate(_a, null, _get_outlineWidth_decorators, { kind: "getter", name: "outlineWidth", static: false, private: false, access: { has: obj => "outlineWidth" in obj, get: obj => obj.outlineWidth }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
678
|
+
__esDecorate(_a, null, _get_underline_decorators, { kind: "getter", name: "underline", static: false, private: false, access: { has: obj => "underline" in obj, get: obj => obj.underline }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
679
|
+
__esDecorate(_a, null, _get_lineThrough_decorators, { kind: "getter", name: "lineThrough", static: false, private: false, access: { has: obj => "lineThrough" in obj, get: obj => obj.lineThrough }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
680
|
+
__esDecorate(_a, null, _get_applyOutlineToUnderline_decorators, { kind: "getter", name: "applyOutlineToUnderline", static: false, private: false, access: { has: obj => "applyOutlineToUnderline" in obj, get: obj => obj.applyOutlineToUnderline }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
681
|
+
__esDecorate(_a, null, _get_outlineColor_decorators, { kind: "getter", name: "outlineColor", static: false, private: false, access: { has: obj => "outlineColor" in obj, get: obj => obj.outlineColor }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
682
|
+
__esDecorate(_a, null, _get_wordDivider_decorators, { kind: "getter", name: "wordDivider", static: false, private: false, access: { has: obj => "wordDivider" in obj, get: obj => obj.wordDivider }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
683
|
+
__esDecorate(_a, null, _get_forceResizeWidth_decorators, { kind: "getter", name: "forceResizeWidth", static: false, private: false, access: { has: obj => "forceResizeWidth" in obj, get: obj => obj.forceResizeWidth }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
684
|
+
if (_metadata) Object.defineProperty(_a, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
685
|
+
})(),
|
|
686
|
+
_a;
|
|
687
|
+
})();
|
|
688
|
+
export { TextBlock };
|
|
678
689
|
let _Registered = false;
|
|
679
690
|
/**
|
|
680
691
|
* Registers the TextBlock class with the type store for serialization support.
|