diff --git a/src/components/DBMTree.vue b/src/components/DBMTree.vue deleted file mode 100644 index 689b651..0000000 --- a/src/components/DBMTree.vue +++ /dev/null @@ -1,197 +0,0 @@ - - - diff --git a/src/components/DragPad.vue b/src/components/DragPad.vue deleted file mode 100644 index bf7923a..0000000 --- a/src/components/DragPad.vue +++ /dev/null @@ -1,133 +0,0 @@ - - - diff --git a/src/components/MovingHead.vue b/src/components/MovingHead.vue deleted file mode 100644 index 294afea..0000000 --- a/src/components/MovingHead.vue +++ /dev/null @@ -1,241 +0,0 @@ -// channel description // 1 Red // 2 Red fine // 3 Green // 4 Green fine // 5 Blue // 6 Blue fine // -7 White // 8 White fine // 9 Linear CTO ??? // 10 Macro Color ??? // 11 Strobe // 12 Dimmer // 13 -Dimer fine // 14 Pan // 15 Pan fine // 16 Tilt // 17 Tilt fine // 18 Function // 19 Reset // 20 Zoom -// 21 Zoom rotation // 22 Shape selection // 23 Shape speed // 24 Shape fade // 25 Shape Red // 26 -Shape Green // 27 Shape Blue // 28 Shape White // 29 Shape Dimmer // 30 Background dimmer // 31 -Shape transition // 32 Shape Offset // 33 Foreground strobe // 34 Background strobe // 35 Background -select - - - - diff --git a/src/components/SettingMovingHead.vue b/src/components/SettingMovingHead.vue deleted file mode 100644 index 6143329..0000000 --- a/src/components/SettingMovingHead.vue +++ /dev/null @@ -1,50 +0,0 @@ - - - diff --git a/src/components/SubMenu.vue b/src/components/SubMenu.vue deleted file mode 100644 index 0ec04fb..0000000 --- a/src/components/SubMenu.vue +++ /dev/null @@ -1,48 +0,0 @@ - - - diff --git a/src/components/dbm/AddDatapoint.vue b/src/components/dbm/AddDatapoint.vue new file mode 100644 index 0000000..e69de29 diff --git a/src/components/dbm/DBMTree.vue b/src/components/dbm/DBMTree.vue new file mode 100644 index 0000000..711fd25 --- /dev/null +++ b/src/components/dbm/DBMTree.vue @@ -0,0 +1,246 @@ + + + + + diff --git a/src/components/dbm/SubMenu.vue b/src/components/dbm/SubMenu.vue new file mode 100644 index 0000000..3c96254 --- /dev/null +++ b/src/components/dbm/SubMenu.vue @@ -0,0 +1,53 @@ + + + diff --git a/src/components/dbm/dataTable.vue b/src/components/dbm/dataTable.vue new file mode 100644 index 0000000..7766fe1 --- /dev/null +++ b/src/components/dbm/dataTable.vue @@ -0,0 +1,36 @@ + + + diff --git a/src/components/DomeLight.vue b/src/components/lights/DomeLight.vue similarity index 72% rename from src/components/DomeLight.vue rename to src/components/lights/DomeLight.vue index c878f61..0d5b3e9 100644 --- a/src/components/DomeLight.vue +++ b/src/components/lights/DomeLight.vue @@ -105,11 +105,14 @@ diff --git a/src/components/lights/DragPad.vue b/src/components/lights/DragPad.vue new file mode 100644 index 0000000..fe3c1c9 --- /dev/null +++ b/src/components/lights/DragPad.vue @@ -0,0 +1,238 @@ + + + + + diff --git a/src/components/lights/LightBarCBL.vue b/src/components/lights/LightBarCBL.vue new file mode 100644 index 0000000..f2e617b --- /dev/null +++ b/src/components/lights/LightBarCBL.vue @@ -0,0 +1,123 @@ + + + diff --git a/src/components/lights/LightSlider.vue b/src/components/lights/LightSlider.vue new file mode 100644 index 0000000..8696235 --- /dev/null +++ b/src/components/lights/LightSlider.vue @@ -0,0 +1,121 @@ + + + diff --git a/src/components/lights/MovingHead.vue b/src/components/lights/MovingHead.vue new file mode 100644 index 0000000..6ea0b61 --- /dev/null +++ b/src/components/lights/MovingHead.vue @@ -0,0 +1,203 @@ +// channel description // 1 Red // 2 Red fine // 3 Green // 4 Green fine // 5 Blue // 6 Blue fine // +7 White // 8 White fine // 9 Linear CTO ??? // 10 Macro Color ??? // 11 Strobe // 12 Dimmer // 13 +Dimer fine // 14 Pan // 15 Pan fine // 16 Tilt // 17 Tilt fine // 18 Function // 19 Reset // 20 Zoom +// 21 Zoom rotation // 22 Shape selection // 23 Shape speed // 24 Shape fade // 25 Shape Red // 26 +Shape Green // 27 Shape Blue // 28 Shape White // 29 Shape Dimmer // 30 Background dimmer // 31 +Shape transition // 32 Shape Offset // 33 Foreground strobe // 34 Background strobe // 35 Background +select + + + + diff --git a/src/components/SettingDomeLight.vue b/src/components/lights/SettingDomeLight.vue similarity index 100% rename from src/components/SettingDomeLight.vue rename to src/components/lights/SettingDomeLight.vue diff --git a/src/components/lights/SettingMovingHead.vue b/src/components/lights/SettingMovingHead.vue new file mode 100644 index 0000000..d9fb49f --- /dev/null +++ b/src/components/lights/SettingMovingHead.vue @@ -0,0 +1,58 @@ + + + diff --git a/src/composables/dbm/dbmTree.ts b/src/composables/dbm/dbmTree.ts new file mode 100644 index 0000000..ff0d18a --- /dev/null +++ b/src/composables/dbm/dbmTree.ts @@ -0,0 +1,158 @@ +import type { Subs } from 'src/models/Subscribe'; +import { ref, nextTick, computed } from 'vue'; +import { setValues } from 'src/services/websocket'; +import { NotifyResponse } from 'src/composables/notify'; +import type { QVueGlobals } from 'quasar'; + +const Subscriptions = ref([]); + +export const dbmData = ref([]); + +export interface TreeNode { + path: string | undefined; + key?: string; // optional: useful for QTree's node-key + value?: string | number | boolean | undefined; + lazy: boolean; + children?: TreeNode[]; +} + +export function buildTree(subs: Subs): TreeNode[] { + type TreeMap = { + [key: string]: { + __children: TreeMap; + uuid?: string; + value?: string | undefined; + lazy: boolean; + }; + }; + + const root: TreeMap = {}; + + Subscriptions.value = subs; + + for (const item of subs) { + const pathParts = item.path?.split(':') ?? []; + let current = root; + + for (let i = 0; i < pathParts.length; i++) { + const part = pathParts[i]; + + if (!part) continue; + + if (!current[part]) { + current[part] = { __children: {}, lazy: true }; + } + + // Optionally attach uuid only at the final part + if (i === pathParts.length - 1 && item.uuid) { + current[part].uuid = item.uuid; + current[part].value = item.value !== undefined ? String(item.value) : ''; + current[part].lazy = item.hasChild ?? false; + } + current = current[part].__children; + } + } + + function convert(map: TreeMap): TreeNode[] { + return Object.entries(map).map(([path, node]) => ({ + path, + key: node.uuid ?? path, // `key` is used by QTree + value: node.value, + lazy: node.lazy, + children: convert(node.__children), + })); + } + + return [ + { + path: 'DBM', + key: '00000000-0000-0000-0000-000000000000', + lazy: true, + children: convert(root), + }, + ]; +} + +export function getTreeElementByPath(path: string) { + return dbmData.value.find((s) => s.path === path); +} + +export function getSubscriptionsByUuid(uid: string | undefined) { + return Subscriptions.value.find((s) => s.uuid === uid); +} + +export function addChildrentoTree(subs: Subs) { + const ZERO_UUID = '00000000-0000-0000-0000-000000000000'; + const existingIds = new Set(Subscriptions.value.map((sub) => sub.uuid)); + const newSubs = subs + .filter((sub) => sub.uuid !== ZERO_UUID) // Skip UUIDs with all zeroes + .filter((sub) => !existingIds.has(sub.uuid)); + + Subscriptions.value.push(...newSubs); + + void nextTick(() => { + dbmData.value = buildTree(Subscriptions.value); + }); +} + +export function removeSubtreeByParentKey(parentKey: string) { + function removeChildrenAndMarkLazy(nodes: TreeNode[], targetKey: string): boolean { + for (const node of nodes) { + if (node.key === targetKey) { + delete node.children; + node.lazy = true; + return true; + } + if (node.children) { + const found = removeChildrenAndMarkLazy(node.children, targetKey); + if (found) return true; + } + } + return false; + } + + removeChildrenAndMarkLazy(dbmData.value, parentKey); +} + +export function getSubscriptionsByPath(path: string | undefined) { + return Subscriptions.value.find((s) => s.path === path); +} + +export function getAllSubscriptions() { + return Subscriptions.value; +} + +export function updateValue( + path1: string, + $q: QVueGlobals, + path2?: string, + path3?: string, + value3?: number, +) { + return computed({ + get() { + const sub = getSubscriptionsByPath(path1); + const value = sub ? Number(sub.value ?? 0) : 0; + return Math.round((100 / 255) * value); + }, + set(val) { + const baseValue = Math.round((255 / 100) * val); + const setPaths = [{ path: path1, value: baseValue }]; + if (path2) { + setPaths.push({ path: path2, value: baseValue }); + } + if (path3) { + setPaths.push({ path: path3, value: value3 ? value3 : baseValue }); + } + setValues(setPaths) + .then((response) => NotifyResponse($q, response)) + .catch((err) => { + NotifyResponse( + $q, + `Failed to update [${path1 + ' ' + path2 + ' ' + path3}]: ${err}`, + 'error', + ); + }); + }, + }); +} diff --git a/src/composables/dbm/useContextMenu.ts b/src/composables/dbm/useContextMenu.ts new file mode 100644 index 0000000..8ed739f --- /dev/null +++ b/src/composables/dbm/useContextMenu.ts @@ -0,0 +1,12 @@ +import { ref } from 'vue'; +import type { TreeNode } from './dbmTree'; + +export const contextMenuRef = ref(); + +export const contextMenuState = ref(); + +export function openContextMenu(event: MouseEvent, node: undefined) { + event.preventDefault(); + contextMenuState.value = node; + contextMenuRef.value?.show(event); +} diff --git a/src/composables/dbmTree.ts b/src/composables/dbmTree.ts deleted file mode 100644 index 28ed466..0000000 --- a/src/composables/dbmTree.ts +++ /dev/null @@ -1,110 +0,0 @@ -import type { Subs } from 'src/models/Subscribe'; -import { ref, nextTick } from 'vue'; - -const Subscriptions = ref([]); - -export const dbmData = ref([]); - -export interface TreeNode { - path: string | undefined; - key?: string; // optional: useful for QTree's node-key - value?: string | number | boolean | undefined; - children?: TreeNode[]; -} - -export function buildTree(subs: Subs): TreeNode[] { - type TreeMap = { - [key: string]: { - __children: TreeMap; - uuid?: string; - value?: string | undefined; - }; - }; - - const root: TreeMap = {}; - - Subscriptions.value = subs; - - for (const item of subs) { - const pathParts = item.path?.split(':') ?? []; - let current = root; - - for (let i = 0; i < pathParts.length; i++) { - const part = pathParts[i]; - - if (!part) continue; - - if (!current[part]) { - current[part] = { __children: {} }; - } - - // Optionally attach uuid only at the final part - if (i === pathParts.length - 1 && item.uuid) { - current[part].uuid = item.uuid; - current[part].value = item.value !== undefined ? String(item.value) : ''; - } - - current = current[part].__children; - } - } - - function convert(map: TreeMap): TreeNode[] { - return Object.entries(map).map(([path, node]) => ({ - path, - key: node.uuid ?? path, // `key` is used by QTree - value: node.value, - children: convert(node.__children), - })); - } - - return [ - { - path: 'DBM', - key: 'DBM', - children: convert(root), - }, - ]; -} - -export function getTreeElementByPath(path: string) { - return dbmData.value.find((s) => s.path === path); -} - -export function getSubscriptionsByUuid(uid: string | undefined) { - return Subscriptions.value.find((s) => s.uuid === uid); -} - -export function addChildrentoTree(subs: Subs) { - Subscriptions.value.push(...subs); - void nextTick(() => { - dbmData.value = buildTree(Subscriptions.value); - }); -} - -export function removeSubtreeByParentKey(parentKey: string) { - // Find the parent node using its uuid - const parent = Subscriptions.value.find((s) => s.uuid === parentKey); - if (!parent || !parent.path) return; - - const parentPath = parent.path; - - // Now filter out the children, but NOT the parent itself - Subscriptions.value = Subscriptions.value.filter((s) => { - // Keep the parent itself (don't remove it) - if (s.uuid === parentKey) return true; - - // Remove any child whose path starts with parentPath + '/' (descendants) - return !s.path?.startsWith(parentPath + ':'); - }); - - // Rebuild the tree after removing children, but keeping the parent - dbmData.value = buildTree(Subscriptions.value); -} - -export function getSubscriptionsByPath(path: string) { - return Subscriptions.value.find((s) => s.path === path); -} - -export function getAllSubscriptions() { - return Subscriptions.value; -} diff --git a/src/composables/useContextMenu.ts b/src/composables/useContextMenu.ts deleted file mode 100644 index 7cd3263..0000000 --- a/src/composables/useContextMenu.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { ref } from 'vue'; - -export const contextMenu = ref({ - show: false, - x: 0, - y: 0, - anchor: 'top left', - self: 'top left', - node: null, -}); - -export function openContextMenu(event: MouseEvent, node: undefined) { - contextMenu.value = { - show: true, - x: event.clientX, - y: event.clientY, - anchor: 'top left', - self: 'top left', - node: node ?? null, - }; -} diff --git a/src/layouts/MainLayout.vue b/src/layouts/MainLayout.vue index e6ea116..ed306cb 100644 --- a/src/layouts/MainLayout.vue +++ b/src/layouts/MainLayout.vue @@ -6,11 +6,11 @@ Light Control -
Version 0.0.1
+
Version {{ version }}
- + Home @@ -29,6 +29,7 @@ diff --git a/src/pages/IndexPage.vue b/src/pages/IndexPage.vue index a0f5b40..db9be6f 100644 --- a/src/pages/IndexPage.vue +++ b/src/pages/IndexPage.vue @@ -2,22 +2,36 @@ - + - - + +