-
Notifications
You must be signed in to change notification settings - Fork 170
/
Copy pathPrimitiveValue.tsx
73 lines (65 loc) · 2.52 KB
/
PrimitiveValue.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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
import { _Symbol } from 'js-slang/dist/alt-langs/scheme/scm-slang/src/stdlib/base';
import { SchemeNumber } from 'js-slang/dist/alt-langs/scheme/scm-slang/src/stdlib/core-math';
import React from 'react';
import { Config } from '../../CseMachineConfig';
import { Layout } from '../../CseMachineLayout';
import { Primitive, ReferenceType } from '../../CseMachineTypes';
import { getTextWidth, isNull, isSourceObject } from '../../CseMachineUtils';
import { ArrayNullUnit } from '../ArrayNullUnit';
import { Binding } from '../Binding';
import { Text } from '../Text';
import { Value } from './Value';
/** this classes encapsulates a primitive value in Source: number, string or null */
export class PrimitiveValue extends Value {
/** the text to be rendered */
readonly text: Text | ArrayNullUnit;
constructor(
/** data */
readonly data: Primitive | _Symbol | SchemeNumber,
/** what this value is being referenced by */
reference: ReferenceType
) {
super();
// derive the coordinates from the main reference (binding / array unit)
if (reference instanceof Binding) {
this._x = reference.x() + getTextWidth(reference.keyString) + Config.TextPaddingX;
this._y = reference.y();
this.text = new Text(this.data, this.x(), this.y(), {
isStringIdentifiable: !isSourceObject(data)
});
} else {
const maxWidth = reference.width();
const textWidth = isNull(this.data)
? 0
: Math.min(
getTextWidth(isSourceObject(data) ? data.toReplString() : String(this.data)),
maxWidth
);
this._x = reference.x() + (reference.width() - textWidth) / 2;
this._y = reference.y() + (reference.height() - Config.FontSize) / 2;
this.text = isNull(this.data)
? new ArrayNullUnit(reference)
: new Text(this.data, this.x(), this.y(), {
maxWidth: maxWidth,
isStringIdentifiable: !isSourceObject(data),
faded: true
});
}
this._width = this.text.width();
this._height = this.text.height();
this.ref = this.text.ref;
this.addReference(reference);
}
handleNewReference(): void {
if (this.references.length > 1)
throw new Error('Primitive values cannot have more than one reference!');
}
markAsReferenced() {
if (this.isReferenced()) return;
super.markAsReferenced();
if (this.text instanceof Text) this.text.options.faded = false;
}
draw(): React.ReactNode {
return <React.Fragment key={Layout.key++}>{this.text.draw()}</React.Fragment>;
}
}