A Widget-level property (border_style/border_thickness/border_color_index), not a per-type config field, since every widget type can have one -- drawn once centrally in device.py's _render_widgets before compositing, using an exact panel palette color so it never dithers. Styles: solid, dashed, dotted, and a fancy double-line picture-frame-mat look. Configurable from a shared "Border" card in every widget's gear-icon dialog.
49 lines
2.0 KiB
JavaScript
49 lines
2.0 KiB
JavaScript
// Shared "Border" card (models.Widget.border_style/border_thickness/
|
|
// border_color_index, _widget_border_fields.html) -- present on every
|
|
// widget type's dialog regardless of widget_type, so this is one shared
|
|
// init function each widget_dialog_<type>.js's init<Type>Dialog() calls,
|
|
// rather than 8 copies of the same slider/swatch/save wiring. Not a
|
|
// page-load script by itself -- frame_layout.js loads it unconditionally
|
|
// (like every other widget_dialog_*.js) since which dialog is open, and
|
|
// therefore which init<Type>Dialog() calls initBorderFields(), varies.
|
|
|
|
function initBorderFields() {
|
|
const styleSelect = document.getElementById('border_style');
|
|
if (!styleSelect) return; // dialog fragment didn't render the border card -- shouldn't happen
|
|
|
|
const thickness = document.getElementById('border_thickness');
|
|
const thicknessValue = document.getElementById('border_thickness_value');
|
|
thickness.addEventListener('input', (e) => {
|
|
thicknessValue.textContent = `${e.target.value}px`;
|
|
});
|
|
|
|
const colorIndexInput = document.getElementById('border_color_index');
|
|
document.querySelectorAll('#border-color-picker .color-swatch').forEach((btn) => {
|
|
btn.addEventListener('click', () => {
|
|
document.querySelectorAll('#border-color-picker .color-swatch').forEach((el) => el.classList.remove('selected'));
|
|
btn.classList.add('selected');
|
|
colorIndexInput.value = btn.dataset.index;
|
|
});
|
|
});
|
|
|
|
document.getElementById('border-config-form').addEventListener('submit', async (e) => {
|
|
e.preventDefault();
|
|
const body = JSON.stringify({
|
|
border_style: styleSelect.value,
|
|
border_thickness: Number(thickness.value),
|
|
border_color_index: Number(colorIndexInput.value),
|
|
});
|
|
try {
|
|
const resp = await fetch(`${window.FRAME_API}/border`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body,
|
|
});
|
|
if (!resp.ok) throw new Error(await apiError(resp));
|
|
showStatus(true, 'Border saved.');
|
|
} catch (err) {
|
|
showStatus(false, err.message);
|
|
}
|
|
});
|
|
}
|