blob: b0364e2e6f4f09f550aa2bd1c76ffd653900d292 (
plain)
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
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
|
const iac = require('iac')
const ansi = require('../util/ansi')
const DisplayElement = require('./DisplayElement')
const FocusElement = require('./form/FocusElement')
module.exports = class Root extends DisplayElement {
// An element to be used as the root of a UI. Handles lots of UI and
// socket stuff.
constructor(interfacer) {
super()
this.interfacer = interfacer
this.selected = null
this.cursorBlinkOffset = Date.now()
interfacer.on('inputData', buf => this.handleData(buf))
}
render() {
this.renderTo(this.interfacer)
}
handleData(buffer) {
if (this.selected) {
const els = this.selected.directAncestors.concat([this.selected])
for (const el of els) {
if (el instanceof FocusElement) {
const shouldBreak = (el.keyPressed(buffer) === false)
if (shouldBreak) {
break
}
el.emit('keypressed', buffer)
}
}
}
}
drawTo(writable) {
writable.write(ansi.moveCursor(0, 0))
writable.write(' '.repeat(this.w * this.h))
}
didRenderTo(writable) {
// Render the cursor, based on the cursorX and cursorY of the currently
// selected element.
if (this.selected && this.selected.cursorVisible) {
if ((Date.now() - this.cursorBlinkOffset) % 1000 < 500) {
writable.write(
ansi.moveCursor(this.selected.absCursorY, this.selected.absCursorX)
)
writable.write(ansi.invert())
writable.write('I')
writable.write(ansi.resetAttributes())
}
writable.write(ansi.showCursor())
writable.write(
ansi.moveCursor(this.selected.absCursorY, this.selected.absCursorX)
)
} else {
writable.write(ansi.hideCursor())
}
if (this.selected && this.selected.cursorVisible) {}
}
cursorMoved() {
// Resets the blinking animation for the cursor. Call this whenever you
// move the cursor.
this.cursorBlinkOffset = Date.now()
}
select(el) {
// Select an element. Calls the unfocus method on the already-selected
// element, if there is one.
if (this.selected) {
this.selected.unfocused()
}
this.selected = el
this.selected.focused()
this.cursorMoved()
}
isChildOrSelfSelected(el) {
if (!this.selected) return false
if (this.selected === el) return true
if (this.selected.directAncestors.includes(el)) return true
return false
}
}
|