Files
NeoIDE/src/functions/monitors.js
2026-01-20 16:50:04 -06:00

172 lines
4.5 KiB
JavaScript

import * as PIXI from "pixi.js-legacy";
const monitors = [];
const MONITOR_PADDING = 8;
const MONITOR_FONT_SIZE = 14;
const MONITOR_MIN_WIDTH = 80;
const MONITOR_BG_COLOR = 0xFF8C1A; // Orange for variables
const MONITOR_TEXT_COLOR = 0xFFFFFF;
export class Monitor {
constructor(app, type, name, getValue, x = 10, y = 10) {
this.app = app;
this.type = type; // 'variable', 'timer', 'answer', etc.
this.name = name;
this.label = name;
this.getValue = getValue;
this.visible = true;
this.dragging = false;
this.container = new PIXI.Container();
this.container.x = x;
this.container.y = y;
this.container.interactive = true;
this.container.buttonMode = true;
// Background
this.background = new PIXI.Graphics();
this.container.addChild(this.background);
// Label text
this.labelText = new PIXI.Text(name, {
fontFamily: 'Arial',
fontSize: MONITOR_FONT_SIZE,
fill: MONITOR_TEXT_COLOR,
fontWeight: 'bold'
});
this.labelText.x = MONITOR_PADDING;
this.labelText.y = MONITOR_PADDING;
this.container.addChild(this.labelText);
// Value text
this.valueText = new PIXI.Text('0', {
fontFamily: 'Arial',
fontSize: MONITOR_FONT_SIZE + 2,
fill: MONITOR_TEXT_COLOR
});
this.valueText.x = MONITOR_PADDING;
this.valueText.y = MONITOR_PADDING + MONITOR_FONT_SIZE + 4;
this.container.addChild(this.valueText);
// Make draggable
this.container.on('pointerdown', this.onDragStart.bind(this));
this.container.on('pointerup', this.onDragEnd.bind(this));
this.container.on('pointerupoutside', this.onDragEnd.bind(this));
this.container.on('pointermove', this.onDragMove.bind(this));
this.app.stage.addChild(this.container);
this.updateDisplay();
monitors.push(this);
}
onDragStart(event) {
this.dragging = true;
this.dragData = event.data;
const pos = this.dragData.getLocalPosition(this.app.stage);
this.dragOffset = {
x: pos.x - this.container.x,
y: pos.y - this.container.y
};
}
onDragEnd() {
this.dragging = false;
this.dragData = null;
}
onDragMove() {
if (this.dragging && this.dragData) {
const pos = this.dragData.getLocalPosition(this.app.stage);
this.container.x = pos.x - this.dragOffset.x;
this.container.y = pos.y - this.dragOffset.y;
}
}
updateDisplay() {
const value = this.getValue();
this.valueText.text = String(value);
// Resize background
const width = Math.max(
MONITOR_MIN_WIDTH,
Math.max(this.labelText.width, this.valueText.width) + MONITOR_PADDING * 2
);
const height = this.labelText.height + this.valueText.height + MONITOR_PADDING * 3;
this.background.clear();
this.background.beginFill(MONITOR_BG_COLOR);
this.background.drawRoundedRect(0, 0, width, height, 8);
this.background.endFill();
this.background.lineStyle(2, 0x000000, 0.2);
this.background.drawRoundedRect(0, 0, width, height, 8);
}
setVisible(visible) {
this.visible = visible;
this.container.visible = visible;
}
destroy() {
this.container.destroy({ children: true });
const index = monitors.indexOf(this);
if (index > -1) {
monitors.splice(index, 1);
}
}
toJSON() {
return {
type: this.type,
name: this.name,
x: this.container.x,
y: this.container.y,
visible: this.visible
};
}
}
export function updateAllMonitors() {
monitors.forEach(monitor => monitor.updateDisplay());
}
export function getMonitor(type, name) {
return monitors.find(m => m.type === type && m.name === name);
}
export function createMonitor(app, type, name, getValue, x, y) {
// Check if monitor already exists
const existing = getMonitor(type, name);
if (existing) {
existing.setVisible(true);
return existing;
}
return new Monitor(app, type, name, getValue, x, y);
}
export function removeMonitor(type, name) {
const monitor = getMonitor(type, name);
if (monitor) {
monitor.destroy();
}
}
export function getAllMonitors() {
return monitors;
}
export function clearAllMonitors() {
monitors.forEach(m => m.destroy());
monitors.length = 0;
}
export function loadMonitors(app, monitorsData, valueGetters) {
monitorsData.forEach(data => {
const getter = valueGetters[data.type]?.[data.name];
if (getter) {
const monitor = new Monitor(app, data.type, data.name, getter, data.x, data.y);
monitor.setVisible(data.visible);
}
});
}