knxdisplay/web-interface/src/utils.js
2026-01-25 21:24:40 +01:00

91 lines
3.2 KiB
JavaScript

import { TYPE_KEYS, WIDGET_DEFAULTS } from './constants';
export function typeKeyFor(type) {
return TYPE_KEYS[type] || 'label';
}
export function clamp(value, min, max) {
if (Number.isNaN(value)) return min;
return Math.max(min, Math.min(max, value));
}
export function minSizeFor(widget) {
const key = typeKeyFor(widget.type);
if (key === 'button') return { w: 60, h: 30 };
if (key === 'led') return { w: 20, h: 20 };
if (key === 'icon') return { w: 24, h: 24 };
return { w: 40, h: 20 };
}
export function hexToRgba(hex, alpha) {
const r = parseInt(hex.slice(1, 3), 16);
const g = parseInt(hex.slice(3, 5), 16);
const b = parseInt(hex.slice(5, 7), 16);
return `rgba(${r},${g},${b},${alpha})`;
}
export function normalizeWidget(w, nextWidgetIdRef) {
const key = typeKeyFor(w.type);
const defaults = WIDGET_DEFAULTS[key];
Object.keys(defaults).forEach((prop) => {
if (prop === 'shadow') return;
if (w[prop] === undefined || w[prop] === null) {
w[prop] = defaults[prop];
}
});
if (!w.shadow) {
w.shadow = { ...defaults.shadow };
} else {
Object.keys(defaults.shadow).forEach((prop) => {
if (w.shadow[prop] === undefined || w.shadow[prop] === null) {
w.shadow[prop] = defaults.shadow[prop];
}
});
}
if (w.visible === undefined || w.visible === null) w.visible = true;
if (w.x === undefined || w.x === null) w.x = 100;
if (w.y === undefined || w.y === null) w.y = 100;
if (w.id === undefined || w.id === null) {
if (nextWidgetIdRef) w.id = nextWidgetIdRef.value++;
}
// Action defaults
if (w.action === undefined) w.action = 0; // BUTTON_ACTIONS.KNX
if (w.targetScreen === undefined) w.targetScreen = 0;
// Icon defaults
if (w.iconCodepoint === undefined) w.iconCodepoint = defaults.iconCodepoint || 0;
if (w.iconPosition === undefined) w.iconPosition = defaults.iconPosition || 0;
if (w.iconSize === undefined) w.iconSize = defaults.iconSize || 1;
if (w.iconGap === undefined) w.iconGap = defaults.iconGap || 8;
// Hierarchy
if (w.parentId === undefined) w.parentId = -1;
}
export function normalizeScreen(screen, nextScreenIdRef, nextWidgetIdRef) {
if (screen.id === undefined || screen.id === null) {
if (nextScreenIdRef) screen.id = nextScreenIdRef.value++;
}
if (!screen.name) screen.name = `Screen ${screen.id}`;
if (screen.mode === undefined || screen.mode === null) screen.mode = 0;
if (!screen.bgColor) screen.bgColor = '#1A1A2E';
if (!Array.isArray(screen.widgets)) screen.widgets = [];
// Modal defaults
if (!screen.modal) {
screen.modal = { x: 0, y: 0, w: 0, h: 0, radius: 12, dim: true };
} else {
if (screen.modal.x === undefined) screen.modal.x = 0;
if (screen.modal.y === undefined) screen.modal.y = 0;
if (screen.modal.w === undefined) screen.modal.w = 0;
if (screen.modal.h === undefined) screen.modal.h = 0;
if (screen.modal.radius === undefined) screen.modal.radius = 12;
if (screen.modal.dim === undefined) screen.modal.dim = true;
}
screen.widgets.forEach(w => normalizeWidget(w, nextWidgetIdRef));
}