sync: wip changes
This commit is contained in:
6
src/terminal/CursorProperties.ts
Normal file
6
src/terminal/CursorProperties.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
export type CursorPosition = {
|
||||
col: number,
|
||||
row: number,
|
||||
}
|
||||
|
||||
export type CursorStyle = 'bar' | 'underline' | 'cell' | 'cell_hollow'
|
||||
@@ -1,49 +1,122 @@
|
||||
import type { Shell } from '../shell/Shell'
|
||||
import type { EventBroadcaster } from '../utils/EventBroadcaster'
|
||||
import sqs from '../utils/sqs'
|
||||
import type { CursorPosition, CursorStyle } from './CursorProperties'
|
||||
|
||||
export class Terminal {
|
||||
private terminal: HTMLElement
|
||||
private cursor: HTMLElement
|
||||
private cellHeight = 16
|
||||
private cellWidth = 8
|
||||
|
||||
constructor() {
|
||||
private cursorPosition: CursorPosition = {
|
||||
col: 0,
|
||||
row: 0,
|
||||
}
|
||||
|
||||
private shell?: Shell
|
||||
|
||||
constructor(broadcaster: EventBroadcaster) {
|
||||
this.terminal = sqs('#terminal')
|
||||
this.cursor = sqs('#cursor')
|
||||
|
||||
this.SetCursorStyle('bar')
|
||||
|
||||
this.ResetCellSize()
|
||||
|
||||
this.NewPage()
|
||||
this.AppendLine('idk./home/idk -> ')
|
||||
}
|
||||
|
||||
LoadShell(shell: Shell) {
|
||||
this.shell = shell
|
||||
this.shell.Init()
|
||||
}
|
||||
|
||||
NewPage() {
|
||||
this.terminal.innerHTML = ''
|
||||
this.SetCursorPosition(0, 0)
|
||||
}
|
||||
|
||||
AppendLine(line: string) {
|
||||
AppendLine(content: string) {
|
||||
this.AdjustCursorPosition(0, 1)
|
||||
|
||||
const paragraph = document.createElement('p')
|
||||
paragraph.style.height = `${this.cellHeight}px`
|
||||
paragraph.style.lineHeight = `${this.cellHeight}px`
|
||||
|
||||
line.split('').forEach((char) => {
|
||||
const span = document.createElement('span')
|
||||
span.textContent = char.replace(' ', '\u00A0')
|
||||
span.style.width = `${this.cellWidth}px`
|
||||
span.style.height = `${this.cellHeight}px`
|
||||
span.style.lineHeight = `${this.cellHeight}px`
|
||||
paragraph.appendChild(span)
|
||||
})
|
||||
paragraph.id = `line-${this.cursorPosition.row}`
|
||||
paragraph.className = 'line'
|
||||
|
||||
this.terminal.appendChild(paragraph)
|
||||
this.AppendCells(content)
|
||||
}
|
||||
|
||||
Write(text: string) {
|
||||
let adjustment = 0
|
||||
|
||||
text.split('').forEach(char => {
|
||||
console.log(this.cursorPosition)
|
||||
|
||||
this.AdjustCursorPosition(adjustment, 0)
|
||||
adjustment = 1
|
||||
|
||||
this.SetCell(char)
|
||||
})
|
||||
}
|
||||
|
||||
SetCell(char: string) {
|
||||
const id = `#cell-${this.cursorPosition.row}_${this.cursorPosition.col}`
|
||||
|
||||
try {
|
||||
sqs(id)
|
||||
} catch (_) {
|
||||
const cell = document.createElement('span')
|
||||
cell.id = id
|
||||
cell.style.width = `${this.cellWidth}px`
|
||||
cell.style.height = `${this.cellHeight}px`
|
||||
cell.style.lineHeight = `${this.cellHeight}px`
|
||||
|
||||
const lineId = `#line-${this.cursorPosition.row}`
|
||||
|
||||
try {
|
||||
sqs(lineId)
|
||||
} catch (_) {
|
||||
// todo: create as many lines as we need
|
||||
for (let i = sqs('#terminal'); ;) {}
|
||||
}
|
||||
} finally {
|
||||
sqs(id).innerText = char[0]
|
||||
}
|
||||
}
|
||||
|
||||
AppendCells(content: string) {
|
||||
const paragraph = sqs(`#line-${this.cursorPosition.row}`)
|
||||
|
||||
content.split('').forEach(char => {
|
||||
paragraph.textContent += char.replace(' ', '\u00A0')
|
||||
this.AdjustCursorPosition(1, 0)
|
||||
})
|
||||
}
|
||||
|
||||
RemoveCells(amount: number) {
|
||||
const paragraph = sqs(`#line-${this.cursorPosition.row}`)
|
||||
paragraph.innerText = paragraph.innerText.slice(
|
||||
0,
|
||||
Math.max(paragraph.innerText.length - amount, 0),
|
||||
)
|
||||
|
||||
this.AdjustCursorPosition(-amount, 0)
|
||||
}
|
||||
|
||||
ResetCellSize() {
|
||||
// dynamically determine cell size using dom
|
||||
const cell = document.createElement('span')
|
||||
cell.textContent = '\\'
|
||||
cell.textContent = 'A'
|
||||
|
||||
this.terminal.appendChild(cell)
|
||||
|
||||
this.cellWidth = cell.scrollWidth
|
||||
this.cellHeight = cell.scrollHeight
|
||||
|
||||
cell.remove()
|
||||
}
|
||||
|
||||
GetHeightCells(): number {
|
||||
@@ -53,4 +126,39 @@ export class Terminal {
|
||||
GetWidthCells(): number {
|
||||
return this.terminal.clientWidth / this.cellWidth
|
||||
}
|
||||
|
||||
UpdateCursor() {
|
||||
this.cursor.style.left = `${this.cursorPosition.col * this.cellWidth}px`
|
||||
this.cursor.style.top = `${this.cursorPosition.row * this.cellHeight}px`
|
||||
}
|
||||
|
||||
GetCursorPosition(): CursorPosition {
|
||||
return this.cursorPosition
|
||||
}
|
||||
|
||||
SetCursorPosition(col: number, row: number) {
|
||||
this.cursorPosition.col = Math.min(
|
||||
this.GetWidthCells(),
|
||||
Math.max(col, 0),
|
||||
)
|
||||
|
||||
this.cursorPosition.row = Math.min(
|
||||
this.GetHeightCells(),
|
||||
Math.max(row, 0),
|
||||
)
|
||||
|
||||
this.UpdateCursor()
|
||||
}
|
||||
|
||||
AdjustCursorPosition(col: number, row: number) {
|
||||
this.SetCursorPosition(this.cursorPosition.col + col, this.cursorPosition.row + row)
|
||||
}
|
||||
|
||||
SetCursorStyle(style: CursorStyle) {
|
||||
switch (style) {
|
||||
default:
|
||||
this.cursor.style.width = '1px'
|
||||
this.cursor.style.height = `${this.cellHeight}px`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user