hadean-old/src/ui/UI.ts

133 lines
2.4 KiB
TypeScript

import blessed from 'neo-blessed';
import ansi from 'sisteransi';
import { getTheme } from '../registries/Themes.js';
export interface Renderable {
render(): void
}
// TODO move this to theme
export const boxStyle = () => {
return {
style: {
border: {
fg: getTheme().border.normal
},
focus: {
border: {
fg: getTheme().border.focused
}
}
},
border: {
type: 'line'
}
};
};
let leftPanel: any;
let rightPanel: any;
let titleBar: any;
let screen: any;
let currentRenderable: Renderable = null;
let started = false;
function assertStarted() {
if(!started) throw new Error('Attempted accessing UI before starting it!');
}
function assertNotStarted() {
if(started) throw new Error('Attempted starting UI when already started!');
}
export function isStarted() {
return started;
}
export const panels = {
get left() {
assertStarted()
return leftPanel;
},
get right() {
assertStarted()
return rightPanel;
},
get screen() {
assertStarted()
return screen;
}
}
export function setTitle(title: string) {
assertStarted();
titleBar.setContent(` ${getTheme().header(title)}{|}${getTheme().subheader('v0.1.0')} {/}`);
}
export function render(thing?: Renderable) {
assertStarted();
if(!!thing) currentRenderable = thing;
currentRenderable.render();
screen.render();
}
export function start() {
assertNotStarted();
screen = blessed.screen({
smartCSR: true,
terminal: 'xterm-256color'
});
leftPanel = blessed.box({
top: 1,
left: 0,
width: '50%',
height: '100%-1',
...boxStyle(),
tags: true
});
rightPanel = blessed.box({
top: 1,
right: 0,
width: '50%',
height: '100%-1',
...boxStyle(),
tags: true
});
titleBar = blessed.box({
top: 0,
left: 0,
width: '100%',
height: 1,
tags: true,
});
screen.append(leftPanel);
screen.append(rightPanel);
screen.append(titleBar);
rightPanel.focus();
process.stdout.write(ansi.cursor.hide);
screen.key(['C-c'], function(ch, key) {
process.stdout.write(ansi.cursor.show);
setTimeout(_ => {
process.exit(0);
})
});
screen.key('f2', () => {
rightPanel.focus();
});
screen.key('f1', () => {
leftPanel.focus();
});
started = true;
setTitle('');
}