<template> <div ref="wall" class="fit items-center justify-evenly wall" @dragenter="onDragEnter" @dragleave="onDragLeave" @dragover="onDragOver" @drop="onDrop" style="background-color: #bce0f0" > <div id="windows" style="position: absolute"> <vue3-resize-drag :w="item.width * ($refs.wall?.clientWidth ?? 0)" :h="item.height * ($refs.wall?.clientHeight ?? 0)" :x=" ($refs.wall?.parentElement?.offsetLeft ?? 0) + ($refs.wall?.offsetLeft ?? 0) + item.x * ($refs.wall?.clientWidth ?? 0) " :y=" ($refs.wall?.parentElement?.offsetTop ?? 0) + ($refs.wall?.offsetTop ?? 0) + item.y * ($refs.wall?.clientHeight ?? 0) " :zIndex=" $store.state.windows_sort.findIndex((element) => element == item.uuid) " :isActive="item.uuid == $store.state.selected_window" :resizeIconSize="14" :isGuide="true" v-for="(item, index) of windows" :key="index" @resizeEndHandler="resizeWindow(item.window_id, $event)" @moveEndHandler="moveWindow(item.window_id, $event)" style="position: fixed" > <window @close_this_window="closeWindow" @close_other_windows="closeOtherWindows" @close_all_windows="closeAllWindows" @replace_this_window="repliceWindow" @top_window="topWindow" @lower_window="lowerWindow" @dblclick="(evt) => windowDBClick(item.window_id)" @edit_volume="edit_volume" @mute_unmute="mute_unmute" @start_polling="start_polling" @stop_polling="stop_polling" @polling_setting="polling_setting" @edit_rect="editRect" :ref="'window_' + item.window_id" :id="'window_' + item.window_id" :uuid="item.uuid" :disable="plan_running" :mouse_area_flag="area_open_window_flag" :signal_source_table_uuid="item.signal_source_table_uuid" :window="item" :plan_running="plan_running" :show_pollong_setting_context_menu="true" class="window fit" > </window> </vue3-resize-drag> </div> <div ref="wall_grids" @click="onWallGridsClick"> <div v-for="row of wall_rows" :key="row" class="row" :style="{ height: item_height + 'px', }" > <div :ref="'item' + (row - 1) * wall_cols + col" v-for="col of wall_cols" :key="col" class="col wall_item wall_item_flag" :style="{ width: item_witdh + 'px', height: item_height + 'px', }" :a_row="row" :a_col="col" > <q-popup-proxy context-menu @show=" { last_context_menu_pos_x = $event.layerX; last_context_menu_pos_y = $event.layerY; } " > <q-list> <q-item :disable="plan_running || !$store.state.power_state" clickable v-close-popup @click="openWindowByLocalFile($event)" > <q-item-section avatar> <q-icon name="open_in_browser" /> </q-item-section> <q-item-section> {{ $t("open window") }} </q-item-section> </q-item> <q-item :disable="plan_running || !$store.state.power_state" clickable v-close-popup @click="closeAllWindows" > <q-item-section avatar> <q-icon name="close" color="red" /> </q-item-section> <q-item-section> {{ $t("close all windwos") }} </q-item-section> </q-item> </q-list> </q-popup-proxy> </div> </div> </div> </div> <div class="mouse_area_mask" v-show="area_open_window_flag" style="position: fixed; pointer-events: none; z-index: 999" :style="{ left: Math.min(area_open_window_rect.start_x, area_open_window_rect.end_x) + 'px', top: Math.min(area_open_window_rect.start_y, area_open_window_rect.end_y) + 'px', width: Math.abs(area_open_window_rect.end_x - area_open_window_rect.start_x) + 'px', height: Math.abs(area_open_window_rect.end_y - area_open_window_rect.start_y) + 'px', }" ></div> <edit-volume-dialog ref="edit_volume_dialog" /> <polling-setting-dialog ref="polling_setting_dialog" /> <file-manage-dialog ref="file_manage_dialog" /> <window-rect-edit-dialog ref="window_rect_edit_dialog" /> </template> <style scoped> .wall { border: 1px solid black; } .wall_item { border: 1px solid gray; } .window { position: absolute; } .wall_item_flag { } .mouse_area_mask { background: #aacceec2; border: 1px solid #0069bee7; } </style> <script lang="ts"> import GlobalData from "src/common/GlobalData"; import { defineComponent, ref, Ref, computed, onMounted } from "vue"; const elementResizeDetectorMaker = require("element-resize-detector"); import { Protocol } from "src/entities/WSProtocol"; import Window from "src/components/Window.vue"; import WindowRectEditDialog from "src/components/WindowRectEditDialog.vue"; import { useI18n } from "vue-i18n"; import { useStore } from "src/store"; import EventBus, { EventNamesDefine } from "src/common/EventBus"; import { WindowOpenNotifyEntity } from "src/entities/MultimediaWindowEntity"; import WindowOtherStateChangeNotifyEntity from "src/entities/WindowOtherStateChangeNotifyEntity"; import { useQuasar } from "quasar"; import { NotifyMessage } from "src/common/ClientConnection"; import EditVolumeDialog from "src/components/EditVolumeDialog.vue"; import PollingSettingDialog from "src/components/PollingSettingDialog.vue"; import vue3ResizeDrag from "../third_lib/vue3-resize-drag/components/vue3-resize-drag/index.vue"; import FileManageDialog from "src/components/FileManageDialog.vue"; import FileEntity from "src/entities/FileEntity"; import { SignalSourceEntity } from "src/entities/SignalSourceEntity"; class Rect { start_x = 0; start_y = 0; end_x = 0; end_y = 0; reset() { this.start_x = 0; this.start_y = 0; this.end_x = 0; this.end_y = 0; } } export default defineComponent({ name: "PageWall", components: { vue3ResizeDrag, Window, EditVolumeDialog, PollingSettingDialog, FileManageDialog, WindowRectEditDialog, }, setup() { const $q = useQuasar(); const $store = useStore(); const $t = useI18n(); const edit_volume_dialog: Ref<any> = ref(null); const polling_setting_dialog: Ref<any> = ref(null); const file_manage_dialog: Ref<any> = ref(null); const window_rect_edit_dialog: Ref<any> = ref(null); const last_context_menu_pos_x = ref(0); const last_context_menu_pos_y = ref(0); const plan_running = computed( () => $store.state.current_running_plan.trim() != "" ); const windows = computed({ get: () => $store.state.windows, set: (val) => $store.commit("setWindows", val), }); const wall_rows = computed({ get: () => $store.state.wall_row, set: (val) => $store.commit("setWallRow", val), }); const wall_cols = computed({ get: () => $store.state.wall_col, set: (val) => $store.commit("setWallCol", val), }); const wall: Ref<HTMLElement | null> = ref(null); const area_open_window_flag = ref(false); const area_open_window_rect = ref(new Rect()); let item_witdh = ref(0); const item_height = ref(0); const calcWallItemWH = () => { item_witdh.value = wall?.value?.parentElement?.offsetWidth ?? 0 / wall_cols.value; if (wall.value && wall.value.parentElement) { const wv_scaler = /*$store.state.device_screen_width / $store.state.device_screen_height*/ 1920 / 1080; item_height.value = wall.value.parentElement.offsetWidth / wv_scaler / wall_rows.value; } else { item_height.value = 0; } item_witdh.value = Math.ceil(item_witdh.value + wall_cols.value) & ~wall_cols.value; item_height.value = Math.ceil(item_height.value + wall_rows.value) & ~wall_rows.value; }; const wallMouseDown = (evt: MouseEvent) => { if (plan_running.value) { return; } if ((evt.ctrlKey || evt.shiftKey || evt.altKey) && wall.value) { let left = wall.value.offsetLeft + (wall.value.parentElement?.offsetLeft ?? 0); let top = wall.value.offsetTop + (wall.value.parentElement?.offsetTop ?? 0); if ( left <= evt.clientX && top <= evt.clientY && left + wall.value.offsetWidth >= evt.clientX && top + wall.value.offsetHeight >= evt.clientY ) { area_open_window_rect.value.start_x = evt.clientX; area_open_window_rect.value.start_y = evt.clientY; area_open_window_rect.value.end_x = evt.clientX; area_open_window_rect.value.end_y = evt.clientY; area_open_window_flag.value = true; evt.stopPropagation(); } } }; const wallMouseUp = (evt: MouseEvent) => { if (area_open_window_flag.value && wall.value) { evt.stopPropagation(); // 大小为0 不开窗 if ( area_open_window_rect.value.start_x != area_open_window_rect.value.end_x && area_open_window_rect.value.start_y != area_open_window_rect.value.end_y ) { // 开窗 let left = wall.value.offsetLeft + (wall.value.parentElement?.offsetLeft ?? 0); let top = wall.value.offsetTop + (wall.value.parentElement?.offsetTop ?? 0); let start_x = Math.min( area_open_window_rect.value.start_x, area_open_window_rect.value.end_x ) - left; let start_y = Math.min( area_open_window_rect.value.start_y, area_open_window_rect.value.end_y ) - top; let end_x = Math.abs( area_open_window_rect.value.end_x - area_open_window_rect.value.start_x ); let end_y = Math.abs( area_open_window_rect.value.end_y - area_open_window_rect.value.start_y ); GlobalData.getInstance() .getCurrentClient() ?.openWindow( new Protocol.OpenWindowRequestEntity( $store.state.selected_signal_source, start_x / wall.value.offsetWidth, start_y / wall.value.offsetHeight, end_x / wall.value.offsetWidth, end_y / wall.value.offsetHeight ) ); } } area_open_window_flag.value = false; area_open_window_rect.value.reset(); }; const wallMouseMove = (evt: MouseEvent) => { if (area_open_window_flag.value) { evt.stopPropagation(); if (wall.value) { let left = wall.value.offsetLeft + (wall.value.parentElement?.offsetLeft ?? 0); let top = wall.value.offsetTop + (wall.value.parentElement?.offsetTop ?? 0); let right = left + wall.value.offsetWidth; let bottom = top + wall.value.offsetHeight; if (evt.clientX < left) { area_open_window_rect.value.end_x = left; } else if (evt.clientX > right) { area_open_window_rect.value.end_x = right; } else { area_open_window_rect.value.end_x = evt.clientX; } if (evt.clientY < top) { area_open_window_rect.value.end_y = top; } else if (evt.clientY > bottom) { area_open_window_rect.value.end_y = bottom; } else { area_open_window_rect.value.end_y = evt.clientY; } } } }; EventBus.getInstance().on(EventNamesDefine.WindowMouseDown, wallMouseDown); EventBus.getInstance().on(EventNamesDefine.WindowMouseMove, wallMouseMove); EventBus.getInstance().on(EventNamesDefine.WindowMouseUp, wallMouseUp); EventBus.getInstance().on( EventNamesDefine.DocumentBodyClick, (evt: PointerEvent) => { if (wall.value) { let flag = false; { let item: HTMLElement | null = evt.srcElement as HTMLElement; while (item) { if (item == wall.value) { flag = true; break; } item = item.parentElement; } } if (!flag) { $store.commit("setSelectedWindow", ""); } } } ); const __temp__size_a__ = 0.00000001; EventBus.getInstance().on( EventNamesDefine.NotifyMessage, (notify: NotifyMessage) => { try { switch (notify.packet.command) { case Protocol.Commands.kCloseWindow: { const temp = JSON.parse(notify.data); if (temp && temp.window_id) { if (temp.window_id << 0 == -1) { $store.commit("cleanWindows", { window_id: temp.window_id, }); } else { $store.commit("removeWindow", { window_id: temp.window_id, }); } } } break; case Protocol.Commands.kMoveWindow: { const temp = JSON.parse(notify.data); if (temp && temp.window_id) { const window = $store.state.windows.find( (item) => item.window_id == temp.window_id ); if (window) { // 先设置一个坐标让数据变动,然后再设置新数据,保证坐标正常刷新 $store.commit("setWindowPropertys", [ { window, property_name: "x", value: (temp.x ?? 0) + __temp__size_a__, }, { window, property_name: "y", value: (temp.y ?? 0) + __temp__size_a__, }, ]); setTimeout(() => { $store.commit("setWindowPropertys", [ { window, property_name: "x", value: temp.x ?? 0, }, { window, property_name: "y", value: temp.y ?? 0, }, ]); }, 0); } } } break; case Protocol.Commands.kResizeWindow: { const temp = JSON.parse(notify.data); if (temp && temp.window_id) { const window = $store.state.windows.find( (item) => item.window_id == temp.window_id ); if (window) { $store.commit("setWindowPropertys", [ { window, property_name: "width", value: (temp.width ?? 0) + __temp__size_a__, }, { window, property_name: "height", value: (temp.width ?? 0) + __temp__size_a__, }, ]); setTimeout(() => { $store.commit("setWindowPropertys", [ { window, property_name: "width", value: temp.width ?? 0, }, { window, property_name: "height", value: temp.height ?? 0, }, ]); }, 0); } } } break; case Protocol.Commands.kOpenWindow: { const temp = JSON.parse(notify.data) as WindowOpenNotifyEntity; if (temp) { $store.commit("pushWindow", temp); } } break; case Protocol.Commands.kWindowOtherStateChanged: { const temp = JSON.parse( notify.data ) as WindowOtherStateChangeNotifyEntity; if (temp && temp.window_id) { const window = $store.state.windows.find( (item) => item.window_id == temp.window_id ); if (window) { $store.commit("setWindowPropertys", [ { window, property_name: "paused", value: temp.paused, }, { window, property_name: "muted", value: temp.muted, }, { window, property_name: "volume", value: temp.volume, }, { window, property_name: "volume", value: temp.volume, }, { window, property_name: "polling", value: temp.polling, }, { window, property_name: "polling_title", value: temp.title, }, { window, property_name: "polling_window_type", value: temp.window_type, }, ]); } } } break; case Protocol.Commands.kTopWindow: { const temp = JSON.parse( notify.data ) as Protocol.TopWindowNotifyEntity; if (temp) { for (const window of $store.state.windows) { if (window && window.window_id != temp.new_window_id) { $store.commit("setWindowProperty", { window, property_name: "focus", value: false, }); } } const window = $store.state.windows.find( (item) => item.window_id == temp.new_window_id ); $store.commit("setWindowProperty", { window, property_name: "focus", value: true, }); $store.commit("topWindow", temp.new_window_id); } } break; case Protocol.Commands.kLowerWindow: { const temp = JSON.parse( notify.data ) as Protocol.LowerWindowNotifyEntity; if (temp) { $store.commit("lowerWindow", temp.window_id); } } break; } } catch {} } ); onMounted(() => { if (wall.value) { elementResizeDetectorMaker().listenTo( wall.value, (element: HTMLElement) => { if (element) { calcWallItemWH(); } } ); } }); interface __Rect { width: number; height: number; x: number; y: number; left: number; top: number; } const moveWindow = (window_id: number, rect: __Rect) => { rect.x = rect.x ?? 0; rect.y = rect.y ?? 0; if (wall.value) { const x = rect.left - (wall.value.parentElement?.offsetLeft ?? 0) - wall.value.offsetLeft; const y = rect.top - (wall.value.parentElement?.offsetTop ?? 0) - wall.value.offsetTop; GlobalData.getInstance() .getCurrentClient() ?.moveWindow( window_id, x / wall.value.clientWidth, y / wall.value.clientHeight ); } }; const resizeWindow = (window_id: number, rect: __Rect) => { rect.width = rect.width ?? 0; rect.height = rect.height ?? 0; rect.left = rect.left ?? 0; rect.top = rect.top ?? 0; if (wall.value) { const x = rect.left - (wall.value.parentElement?.offsetLeft ?? 0) - wall.value.offsetLeft; const y = rect.top - (wall.value.parentElement?.offsetTop ?? 0) - wall.value.offsetTop; GlobalData.getInstance() .getCurrentClient() ?.setWindowGeometry( window_id, x / wall.value.clientWidth, y / wall.value.clientHeight, rect.width / wall.value.clientWidth, rect.height / wall.value.clientHeight ); } }; return { windows, wall, window_rect_edit_dialog, wall_rows, wall_cols, item_witdh, item_height, plan_running, edit_volume_dialog, polling_setting_dialog, file_manage_dialog, area_open_window_rect, area_open_window_flag, last_context_menu_pos_x, last_context_menu_pos_y, loga(a: any) { console.log(a); }, async onDrop(e: DragEvent) { e.preventDefault(); let target = e.target as any; // 有可能是窗口的子节点收到了拖拽信息,需要找到真正的窗口节点来判断 const find_parent_dom = (dom: HTMLElement, classess: string[]) => { let parent: HTMLElement | null = dom; while (parent) { if (parent) { for (const clazz of classess) { if (clazz) { if (parent.classList.contains(clazz)) { return parent; } } } parent = parent.parentElement; } else { break; } } return parent; }; if (target) { const temp = find_parent_dom(target, [ "wall_item_flag", "window_flag", ]); if (temp) { target = temp; } } if (target) { target.classList.remove("drag-enter"); } if (plan_running.value) { $q.notify({ type: "warning", message: $t.t("plan running! can't open window!"), position: "top", timeout: 1500, }); return; } const type = e.dataTransfer?.getData("type"); const uuid = e.dataTransfer?.getData("uuid"); if (uuid && uuid.length > 0 && type && type.length > 0) { const signal_sources = GlobalData.getInstance().signal_source.filter( (item) => (item as any)?.uuid == uuid ); { const dom_element: HTMLElement | null = target as HTMLElement; if (wall.value && dom_element) { let x = 0; let y = 0; let width = 0; let height = 0; let muted = true; let paused = false; let play_speed = 1; let find_flag = false; let find_window = 0; if (dom_element.classList.contains("wall_item_flag")) { // 开窗 const cell_width = 1 / $store.state.wall_col; const cell_height = 1 / $store.state.wall_row; let col = 0; let row = 0; try { col = parseInt(dom_element.getAttribute("a_col") ?? "1") - 1; row = parseInt(dom_element.getAttribute("a_row") ?? "1") - 1; if (isNaN(row)) { row = 0; } if (isNaN(col)) { col = 0; } } catch {} x = col * cell_width; y = row * cell_height; width = cell_width; height = cell_height; } else if (dom_element.classList.contains("window_flag")) { // 拖拽信号源替换窗口 后面还有一处替换窗口 const rep_uuid = dom_element.getAttribute("uuid"); if (rep_uuid) { let window = $store.state.windows.find( (item) => item.uuid == rep_uuid ); if (window) { x = window.x; y = window.y; width = window.width; height = window.height; muted = window.muted; paused = window.paused; play_speed = window.play_speed; find_window = window.window_id; find_flag = true; } } } if (e.altKey) { if (window_rect_edit_dialog.value) { try { const result = await window_rect_edit_dialog.value.showDialogAsync( x * $store.state.device_screen_width, y * $store.state.device_screen_height, width * $store.state.device_screen_width, height * $store.state.device_screen_height ); if (result) { x = result.x / $store.state.device_screen_width; y = result.y / $store.state.device_screen_height; width = result.width / $store.state.device_screen_width; height = result.height / $store.state.device_screen_height; } else { // 点击了取消按钮 return; } } catch { return; } } } if (find_flag) { GlobalData.getInstance() .getCurrentClient() ?.closeWindow(find_window); } setTimeout(() => { if (!window) { return; } switch (type) { case "polling": { const open_polling_request = new Protocol.OpenPollingRequestEntity( uuid, x, y, width, height ); open_polling_request.muted = muted; open_polling_request.paused = paused; open_polling_request.play_speed = play_speed; GlobalData.getInstance() .getCurrentClient() ?.openPolling(open_polling_request); } break; case "signal_source": { const open_window_request = new Protocol.OpenWindowRequestEntity( uuid, x, y, width, height ); open_window_request.muted = muted; open_window_request.paused = paused; open_window_request.play_speed = play_speed; if (signal_sources.length) { const signal_source = signal_sources[0]; if (signal_source) { GlobalData.getInstance() .getCurrentClient() ?.openWindow(open_window_request); } } } break; } }, 50); } } } }, onDragEnter(e: DragEvent) { e.stopPropagation(); let target: HTMLElement | null = e.target as HTMLElement; if (target && target.draggable !== true) { while ( target && !target.classList.contains("window_flag") && !target.classList.contains("wall_item_flag") ) { target = target.parentElement; } target?.classList.add("drag-enter"); } }, onDragLeave(e: DragEvent) { let target: HTMLElement = e.target as HTMLElement; target?.classList.remove("drag-enter"); }, onDragOver(e: DragEvent) { if (!plan_running.value && $store.state.power_state) { e.preventDefault(); } }, onWallGridsClick(e: MouseEvent) { e.stopPropagation(); $store.commit("setSelectedWindow", ""); }, moveWindow, resizeWindow, closeAllWindows() { GlobalData.getInstance().getCurrentClient()?.closeWindow(-1); }, topWindow(window_id: number) { GlobalData.getInstance().getCurrentClient()?.focusIn(window_id); }, lowerWindow(window_id: number) { GlobalData.getInstance().getCurrentClient()?.lowerWindow(window_id); }, closeOtherWindows(window_id: number) { for (const window of $store.state.windows) { if (window && window.window_id != window_id) { GlobalData.getInstance() .getCurrentClient() ?.closeWindow(window.window_id); } } }, windowDBClick(window_id: number) { if (plan_running.value) { return; } GlobalData.getInstance().getCurrentClient()?.windowFitGrid(window_id); }, closeWindow(window_id: number) { GlobalData.getInstance().getCurrentClient()?.closeWindow(window_id); }, edit_volume(window_id: number) { const window = windows.value.find( (element) => element && element.window_id == window_id ); if (window) { edit_volume_dialog.value?.showDialog(window_id, window.volume); } }, mute_unmute(window_id: number) { const window = windows.value.find( (element) => element && element.window_id == window_id ); if (window) { if (window.muted) { GlobalData.getInstance() .getCurrentClient() ?.unmuteWindow(window_id); } else { GlobalData.getInstance().getCurrentClient()?.muteWindow(window_id); } } }, start_polling(window_id: number) { const window = windows.value.find( (element) => element && element.window_id == window_id ); if (window) { GlobalData.getInstance().getCurrentClient()?.startPolling(window_id); } }, stop_polling(window_id: number) { const window = windows.value.find( (element) => element && element.window_id == window_id ); if (window) { GlobalData.getInstance().getCurrentClient()?.stopPolling(window_id); } }, async editRect(window_id: number) { if (window_rect_edit_dialog.value) { try { const window = $store.state.windows.find( (element) => element && element.window_id == window_id ); if (window) { const result = await window_rect_edit_dialog.value.showDialogAsync( window.x * $store.state.device_screen_width, window.y * $store.state.device_screen_height, window.width * $store.state.device_screen_width, window.height * $store.state.device_screen_height ); if (result) { let { x, y, width, height } = result; x /= $store.state.device_screen_width; y /= $store.state.device_screen_height; width /= $store.state.device_screen_width; height /= $store.state.device_screen_height; GlobalData.getInstance() .getCurrentClient() ?.setWindowGeometry(window_id, x, y, width, height); } } } catch {} } }, async polling_setting(window_id: number) { const window = windows.value.find( (element) => element && element.window_id == window_id ); if (window) { if (window.polling) { $q.notify({ color: "positive", icon: "done", message: $t.t("please stop polling first") + "!", position: "top", timeout: 1500, }); return; } const polling = GlobalData.getInstance()._pollings.find( (element) => element && element.uuid == window.polling_uuid ); const signal_source = GlobalData.getInstance().signal_source.find( (element) => element && element.uuid == window.signal_source_table_uuid ); const result = await polling_setting_dialog.value.showDialogAsync( polling ? polling.name : signal_source ? signal_source.name : null, polling ? polling.polling_signal_sources : [] ); if (result) { const { name, datas } = result; if (name && datas) { try { const resposne = await GlobalData.getInstance() .getCurrentClient() ?.setWindowPollingData(window_id, name, datas); if (resposne) { if (resposne.success) { $q.notify({ color: "positive", icon: "done", message: $t.t("set polling data") + $t.t("success") + "!", position: "top", timeout: 1500, }); } else { $q.notify({ color: "negative", icon: "warning", message: $t.t("set polling data") + $t.t("failed") + "!", position: "top", timeout: 1500, }); } } } catch (e) { console.log(e); } } } } }, async openWindowByLocalFile(event: MouseEvent) { if (!wall.value) { return; } const obj = await file_manage_dialog.value.showDialogAsync( "select", ".mp4;.avi;.ts;.webm;.flv;.mkv;.wmv;.jpg;.png;" ); if (obj) { interface __I { path: string; file: FileEntity; } let { path, file }: __I = obj; if (path && file) { const full_path = (path + "/" + file.name).replace(/\\/g, "/"); const entity: SignalSourceEntity = new SignalSourceEntity(); if ( file.name.endsWith("mp4") || file.name.endsWith("avi") || file.name.endsWith("ts") || file.name.endsWith("webm") || file.name.endsWith("flv") || file.name.endsWith("mkv") || file.name.endsWith("wmv") ) { entity.window_type = "EwindowType::Multimedia"; entity.media_url = JSON.stringify([full_path]); } else { entity.window_type = "EwindowType::Image"; entity.media_url = full_path; } entity.name = file.name; entity.local_file_flag = true; entity.group_uuid = ""; try { const response = await GlobalData.getInstance() .getCurrentClient() ?.addSignalSource(entity); if (response && response.success) { const cell_width = 1.0 / $store.state.wall_col; const cell_height = 1.0 / $store.state.wall_row; const col = Math.floor( last_context_menu_pos_x.value / wall.value.offsetWidth / cell_width ); const row = Math.floor( last_context_menu_pos_y.value / wall.value.offsetHeight / cell_height ); const x = col * cell_width; const y = row * cell_height; if (!isNaN(x) && !isNaN(y)) { const open_window_request = new Protocol.OpenWindowRequestEntity( response.uuid, x, y, cell_width, cell_height ); GlobalData.getInstance() .getCurrentClient() ?.openWindow(open_window_request); } } } catch {} } } }, async repliceWindow(window_id: number) { // 选择信号源替换窗口,上面还有一处拖拽信号源替换 if (!wall.value) { return; } const old_window = $store.state.windows.find( (element) => element && element.window_id == window_id ); if (old_window) { const old_signal_source = GlobalData.getInstance().signal_source.find( (element) => element && element.uuid == old_window.signal_source_table_uuid ); if (old_signal_source) { const obj = await file_manage_dialog.value.showDialogAsync( "select", ".mp4;.avi;.ts;.webm;.flv;.mkv;.wmv;.jpg;.png;" ); if (obj) { interface __I { path: string; file: FileEntity; } let { path, file }: __I = obj; if (path && file) { const full_path = (path + "/" + file.name).replace(/\\/g, "/"); const entity: SignalSourceEntity = new SignalSourceEntity(); if ( file.name.endsWith("mp4") || file.name.endsWith("avi") || file.name.endsWith("ts") || file.name.endsWith("webm") || file.name.endsWith("flv") || file.name.endsWith("mkv") || file.name.endsWith("wmv") ) { entity.window_type = "EwindowType::Multimedia"; entity.media_url = JSON.stringify([full_path]); } else { entity.window_type = "EwindowType::Image"; entity.media_url = full_path; } entity.name = file.name; entity.local_file_flag = true; entity.group_uuid = ""; try { const response = await GlobalData.getInstance() .getCurrentClient() ?.addSignalSource(entity); if (response && response.success) { const open_window_request = new Protocol.OpenWindowRequestEntity( response.uuid, old_window.x, old_window.y, old_window.width, old_window.height ); open_window_request.muted = old_window.muted; open_window_request.volume = old_window.volume; open_window_request.paused = old_window.paused; open_window_request.play_speed = old_window.play_speed; GlobalData.getInstance() .getCurrentClient() ?.closeWindow(old_window.window_id); GlobalData.getInstance() .getCurrentClient() ?.openWindow(open_window_request); } } catch {} } } } } }, }; }, }); </script>