-
Notifications
You must be signed in to change notification settings - Fork 170
/
Copy pathLevel.tsx
73 lines (67 loc) · 2.35 KB
/
Level.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 React from 'react';
import { Group, Rect } from 'react-konva';
import CseMachine from '../CseMachine';
import { Config, ShapeDefaultProps } from '../CseMachineConfig';
import { ControlStashConfig } from '../CseMachineControlStashConfig';
import { Layout } from '../CseMachineLayout';
import { EnvTreeNode } from '../CseMachineTypes';
import { Frame } from './Frame';
import { Visible } from './Visible';
/** this class encapsulates a level of frames to be drawn with the same y values */
export class Level extends Visible {
/** all the frames in this level */
readonly frames: Frame[] = [];
constructor(
/** the level of this */
readonly parentLevel: Level | null,
/** the environment tree nodes contained in this level */
readonly envTreeNodes: EnvTreeNode[]
) {
super();
this._x = CseMachine.getControlStash()
? ControlStashConfig.ControlPosX + ControlStashConfig.ControlItemWidth + Config.CanvasPaddingX
: Config.CanvasPaddingX;
this._y = Config.CanvasPaddingY;
if (CseMachine.getControlStash() && !this.parentLevel) {
this._y += ControlStashConfig.StashItemHeight + ControlStashConfig.ControlItemTextPadding * 3;
}
if (this.parentLevel) {
this._y += this.parentLevel.height() + this.parentLevel.y();
}
let prevFrame: Frame | null = null;
envTreeNodes.forEach(e => {
e.level = this;
const newFrame = new Frame(e, prevFrame);
e.frame = newFrame;
this.frames.push(newFrame);
prevFrame = newFrame;
});
// get the max height of all the frames in this level including the label
this._height = this.frames.reduce<number>(
(maxHeight, frame) => Math.max(maxHeight, frame.totalHeight),
0
);
const lastFrame = this.frames[this.frames.length - 1];
// derive the width of this level from the last frame
this._width = lastFrame.x() + lastFrame.totalWidth - this.x() + Config.LevelPaddingX;
}
destroy() {
this.ref.current.destroyChildren();
}
draw(): React.ReactNode {
return (
<Group key={Layout.key++} ref={this.ref}>
<Rect
{...ShapeDefaultProps}
x={this.x()}
y={this.y()}
width={this.width()}
height={this.height()}
key={Layout.key++}
listening={false}
/>
{this.frames.map(frame => frame.draw())}
</Group>
);
}
}