添加窗口的开关移动修改大小功能

This commit is contained in:
fangxiang 2021-08-06 17:24:41 +08:00
parent 9e05658b3b
commit d573ae8058
8 changed files with 654 additions and 115 deletions

View File

@ -1,4 +1,5 @@
import { Protocol } from "src/entities/WSProtocol"; import { Protocol } from "src/entities/WSProtocol";
import EventBus, { EventNamesDefine } from "./EventBus";
export default class ClientConnection { export default class ClientConnection {
ws: WebSocket | null = null; ws: WebSocket | null = null;
@ -16,15 +17,6 @@ export default class ClientConnection {
| ((this: ClientConnection, logined: boolean) => void) | ((this: ClientConnection, logined: boolean) => void)
| null = null; | null = null;
public message_callback:
| ((
this: ClientConnection,
command: string,
packet: Protocol.Commands,
data: string
) => void)
| null = null;
constructor( constructor(
url: string, url: string,
user_name?: string | null, user_name?: string | null,
@ -102,6 +94,7 @@ export default class ClientConnection {
onMessage(ev: MessageEvent) { onMessage(ev: MessageEvent) {
try { try {
const packet = JSON.parse(ev.data) as Protocol.PacketEntity; const packet = JSON.parse(ev.data) as Protocol.PacketEntity;
if (packet) { if (packet) {
if (packet.has_exception) { if (packet.has_exception) {
console.error(ev.data); console.error(ev.data);
@ -132,11 +125,15 @@ export default class ClientConnection {
f(false, packet, ev.data); f(false, packet, ev.data);
this.rpc_map.delete(packet.rpc_id); this.rpc_map.delete(packet.rpc_id);
} }
} } else {
if (this.message_callback) { EventBus.getInstance().emit(EventNamesDefine.ResponseMessage, {
this.message_callback(packet.command, packet, ev.data); packet: packet,
data: ev.data,
});
} }
} }
} else {
console.error("unknow command: " + packet.command, packet);
} }
} }
} catch (e) { } catch (e) {
@ -215,4 +212,24 @@ export default class ClientConnection {
console.error(e); console.error(e);
} }
} }
public moveWindow(window_id: number, x: number, y: number) {
this.ws?.send(
JSON.stringify(new Protocol.MoveWindowRequestEntity(window_id, x, y))
);
}
public resizeWindow(window_id: number, width: number, height: number) {
this.ws?.send(
JSON.stringify(
new Protocol.ResizeWindowRequestEntity(window_id, width, height)
)
);
}
public closeWindow(window_id: number) {
this.ws?.send(
JSON.stringify(new Protocol.CloseWindowRequestEntity(window_id))
);
}
} }

View File

@ -14,4 +14,5 @@ export default class EventBus extends EventEmitter {
export namespace EventNamesDefine { export namespace EventNamesDefine {
export const UnSelectAllWindows = "unselect_all_windows"; export const UnSelectAllWindows = "unselect_all_windows";
export const WindowResize = "windowResize"; export const WindowResize = "windowResize";
export const ResponseMessage = "onResponseData";
} }

View File

@ -1,20 +1,133 @@
<template> <template>
<div <div
:class="selected ? 'window_selected' : 'window_normal'" class="window"
:class="selected ? 'window_selected top' : 'window_normal'"
@click="onClick" @click="onClick"
@mousedown="onMouseDown" @mousedown="onMouseDown"
@mousemove="onMouseMove" @mousemove="onMouseMove"
@mouseleave="onMouseLeave" @mouseleave="onMouseLeave"
@mouseup="onMouseLeave" @mouseup="onMouseLeave"
> >
<q-popup-proxy context-menu>
<q-popup-proxy context-menu />
<q-list>
<q-item
clickable
v-close-popup
@click="$emit('close_this_window', $props.window.window_id)"
>
<q-item-section> {{ $t("close this window") }} </q-item-section>
</q-item>
<q-item
clickable
v-close-popup
@click="$emit('close_other_windows', $props.window.window_id)"
>
<q-item-section>
{{ $t("close other windows") }}
</q-item-section>
</q-item>
<q-item
clickable
v-close-popup
@click="$emit('close_all_windows', $props.window.window_id)"
>
<q-item-section> {{ $t("close all windwos") }} </q-item-section>
</q-item>
</q-list>
</q-popup-proxy>
<div class="title_bar full-width"> <div class="title_bar full-width">
<q-icon :name="getItemIcon(signal_source.window_type)" /> <q-icon :name="getItemIcon(signal_source.window_type)" />
<span>{{ signal_source.name }}</span> <span>{{ signal_source.name }}</span>
</div> </div>
<div
v-if="selected && can_resize"
class="resize_div absolute_up"
ref="resize_up"
@mousedown="onMouseDown"
@mousemove="(evt) => onResizeMouseMove(evt, flags.up_flag)"
@mouseleave="onMouseLeave"
@mouseup="onMouseLeave"
></div>
<div
v-if="selected && can_resize"
class="resize_div absolute_down"
ref="resize_down"
@mousedown="onMouseDown"
@mousemove="(evt) => onResizeMouseMove(evt, flags.down_flag)"
@mouseleave="onMouseLeave"
@mouseup="onMouseLeave"
></div>
<div
v-if="selected && can_resize"
class="resize_div absolute_left"
ref="resize_left"
@mousedown="onMouseDown"
@mousemove="(evt) => onResizeMouseMove(evt, flags.left_flag)"
@mouseleave="onMouseLeave"
@mouseup="onMouseLeave"
></div>
<div
v-if="selected && can_resize"
class="resize_div absolute_right"
ref="resize_right"
@mousedown="onMouseDown"
@mousemove="(evt) => onResizeMouseMove(evt, flags.right_flag)"
@mouseleave="onMouseLeave"
@mouseup="onMouseLeave"
></div>
<div
v-if="selected && can_resize"
class="resize_div absolute_left_up"
ref="resize_left_up"
@mousedown="onMouseDown"
@mousemove="
(evt) => onResizeMouseMove(evt, flags.up_flag | flags.left_flag)
"
@mouseleave="onMouseLeave"
@mouseup="onMouseLeave"
></div>
<div
v-if="selected && can_resize"
class="resize_div absolute_right_up"
ref="resize_right_up"
@mousedown="onMouseDown"
@mousemove="
(evt) => onResizeMouseMove(evt, flags.up_flag | flags.right_flag)
"
@mouseleave="onMouseLeave"
@mouseup="onMouseLeave"
></div>
<div
v-if="selected && can_resize"
class="resize_div absolute_left_down"
ref="resize_left_down"
@mousedown="onMouseDown"
@mousemove="
(evt) => onResizeMouseMove(evt, flags.down_flag | flags.left_flag)
"
@mouseleave="onMouseLeave"
@mouseup="onMouseLeave"
></div>
<div
v-if="selected && can_resize"
class="resize_div absolute_right_down"
ref="resize_right_down"
@mousedown="onMouseDown"
@mousemove="
(evt) => onResizeMouseMove(evt, flags.down_flag | flags.right_flag)
"
@mouseleave="onMouseLeave"
@mouseup="onMouseLeave"
></div>
</div> </div>
</template> </template>
<style scoped> <style scoped>
.window {
}
.window_selected { .window_selected {
outline-style: dashed; outline-style: dashed;
outline-color: #166fab; outline-color: #166fab;
@ -27,6 +140,84 @@
.title_bar { .title_bar {
border: 1px solid black; border: 1px solid black;
} }
.top {
z-index: 1;
}
.resize_div {
background: gray;
width: 32px;
height: 32px;
}
.absolute_up {
position: absolute;
top: -16px;
left: calc(50% - 16px);
}
.absolute_down {
position: absolute;
bottom: -16px;
left: calc(50% - 16px);
}
div.absolute_up,
div.absolute_down {
cursor: s-resize;
}
.absolute_left {
position: absolute;
top: calc(50% - 16px);
left: -16px;
}
.absolute_right {
position: absolute;
top: calc(50% - 16px);
right: -16px;
}
div.absolute_left,
div.absolute_right {
cursor: w-resize;
}
.absolute_left_up {
position: absolute;
top: -16px;
left: -16px;
}
.absolute_left_down {
position: absolute;
bottom: -16px;
left: -16px;
}
.absolute_right_up {
position: absolute;
top: -16px;
right: -16px;
}
.absolute_right_down {
position: absolute;
bottom: -16px;
right: -16px;
}
div.absolute_left_up,
div.absolute_right_down {
cursor: se-resize;
}
div.absolute_right_up,
div.absolute_left_down {
cursor: ne-resize;
}
</style> </style>
<script lang="ts"> <script lang="ts">
@ -36,6 +227,21 @@ import GlobalData from "src/common/GlobalData";
import { defineComponent, ref } from "vue"; import { defineComponent, ref } from "vue";
import { useStore } from "src/store"; import { useStore } from "src/store";
class _Flags {
get up_flag() {
return 0x0001;
}
get down_flag() {
return 0x0002;
}
get left_flag() {
return 0x0004;
}
get right_flag() {
return 0x0008;
}
}
export default defineComponent({ export default defineComponent({
name: "ComponentWindow", name: "ComponentWindow",
@ -50,7 +256,13 @@ export default defineComponent({
required: true, required: true,
}, },
}, },
emits: ["move_window"], emits: [
"reset_geometry_offset",
"commit_geometry",
"close_this_window",
"close_other_windows",
"close_all_windows",
],
setup(props, { emit }) { setup(props, { emit }) {
const $store = useStore(); const $store = useStore();
@ -59,6 +271,8 @@ export default defineComponent({
); );
let selected = ref(false); let selected = ref(false);
let can_move = ref(true);
let can_resize = ref(true);
EventBus.getInstance().on(EventNamesDefine.UnSelectAllWindows, () => { EventBus.getInstance().on(EventNamesDefine.UnSelectAllWindows, () => {
selected.value = false; selected.value = false;
@ -67,8 +281,6 @@ export default defineComponent({
let mouse_down_flag = false; let mouse_down_flag = false;
let mouse_last_pos_x = 0; let mouse_last_pos_x = 0;
let mouse_last_pos_y = 0; let mouse_last_pos_y = 0;
let can_move = true;
let can_resize = true;
const cleanMouseDownFlag = () => { const cleanMouseDownFlag = () => {
mouse_down_flag = false; mouse_down_flag = false;
@ -76,29 +288,75 @@ export default defineComponent({
mouse_last_pos_y = 0; mouse_last_pos_y = 0;
}; };
const flags = new _Flags();
return { return {
signal_source, signal_source,
selected, selected,
can_move,
can_resize,
flags,
onClick(evt: PointerEvent) { onClick(evt: PointerEvent) {
EventBus.getInstance().emit(EventNamesDefine.UnSelectAllWindows); EventBus.getInstance().emit(EventNamesDefine.UnSelectAllWindows);
selected.value = true; selected.value = true;
}, },
onMouseDown(evt: MouseEvent) { onMouseDown(evt: MouseEvent) {
if (selected.value) {
if (evt.button == 0) { if (evt.button == 0) {
mouse_down_flag = true; mouse_down_flag = true;
mouse_last_pos_x = evt.x; mouse_last_pos_x = evt.x;
mouse_last_pos_y = evt.y; mouse_last_pos_y = evt.y;
} }
}
}, },
onMouseMove(evt: MouseEvent) { onMouseMove(evt: MouseEvent) {
if (mouse_down_flag && selected.value) { if (can_move.value && mouse_down_flag && selected.value) {
emit( emit(
"move_window", "reset_geometry_offset",
$store,
props.window, props.window,
evt.x - mouse_last_pos_x, evt.x - mouse_last_pos_x,
evt.y - mouse_last_pos_y evt.y - mouse_last_pos_y,
0,
0
);
mouse_last_pos_x = evt.x;
mouse_last_pos_y = evt.y;
}
},
onResizeMouseDown(evt: MouseEvent) {},
onResizeMouseMove(evt: MouseEvent, dir: number) {
if (can_resize.value && mouse_down_flag && selected.value) {
const h = evt.x - mouse_last_pos_x;
const v = evt.y - mouse_last_pos_y;
let x_offset = 0;
let y_offset = 0;
let width_offset = 0;
let height_offset = 0;
if (dir & flags.up_flag) {
y_offset += v;
height_offset -= v;
}
if (dir & flags.down_flag) {
height_offset += v;
}
if (dir & flags.left_flag) {
x_offset += h;
width_offset -= h;
}
if (dir & flags.right_flag) {
width_offset += h;
}
emit(
"reset_geometry_offset",
props.window,
x_offset,
y_offset,
width_offset,
height_offset
); );
mouse_last_pos_x = evt.x; mouse_last_pos_x = evt.x;
@ -108,11 +366,17 @@ export default defineComponent({
cleanMouseDownFlag, cleanMouseDownFlag,
onMouseLeave(evt: MouseEvent) { onMouseLeave(evt: MouseEvent) {
if (selected.value && mouse_down_flag) {
cleanMouseDownFlag(); cleanMouseDownFlag();
emit("commit_geometry", props.window);
}
}, },
onMouseUp(evt: MouseEvent) { onMouseUp(evt: MouseEvent) {
if (selected.value && mouse_down_flag) {
cleanMouseDownFlag(); cleanMouseDownFlag();
emit("commit_geometry", props.window);
}
}, },
getItemIcon(item_type: string) { getItemIcon(item_type: string) {

View File

@ -1,11 +1,35 @@
import BaseEntity from "./BaseEntity"; import BaseEntity from "./BaseEntity";
import { SignalSourceEntity } from "./SignalSourceEntity"; import { SignalSourceEntity } from "./SignalSourceEntity";
import { Protocol } from "./WSProtocol";
export default class MultimediaWindowEntity extends BaseEntity { export class MultimediaWindowEntity extends BaseEntity {
x: number = 0; x: number = 0;
y: number = 0; y: number = 0;
width: number = 0; width: number = 0;
height: number = 0; height: number = 0;
signal_source_table_uuid: string = ""; signal_source_table_uuid: string = "";
signal_source_table_entity: SignalSourceEntity = new SignalSourceEntity(); // signal_source_table_entity: SignalSourceEntity = new SignalSourceEntity();
}
export class WindowOpenNotifyEntity extends MultimediaWindowEntity {
public static get FLAG_REQUEST() {
return 0;
}
public static get FLAG_RESPONSE() {
return 1;
}
public static get FLAG_NOTIFY() {
return 2;
}
/** 是否出现异常,如果是异常,则为 ExceptionEntity */
has_exception = false;
/** 0: 请求 1: 响应 */
flag = WindowOpenNotifyEntity.FLAG_REQUEST;
/** rpc 消息 ID默认 0 */
rpc_id = 0;
/** 命令 */
command = Protocol.Commands.kUnKnowCommand;
window_id: number = 0;
} }

View File

@ -1,6 +1,6 @@
import { SignalSourceEntity } from "./SignalSourceEntity"; import { SignalSourceEntity } from "./SignalSourceEntity";
import ApplicationConfigEntity from "./ApplicationConfigEntity"; import ApplicationConfigEntity from "./ApplicationConfigEntity";
import MultimediaWindowEntity from "./MultimediaWindowEntity"; import { WindowOpenNotifyEntity } from "./MultimediaWindowEntity";
export namespace Protocol { export namespace Protocol {
export class Commands { export class Commands {
@ -41,6 +41,22 @@ export namespace Protocol {
return Commands.PROTOCOL_PREFIX + "RpcGetApplicationConfig"; return Commands.PROTOCOL_PREFIX + "RpcGetApplicationConfig";
} }
public static get kMoveWindow() {
return Commands.PROTOCOL_PREFIX + "MoveWindow";
}
public static get kResizeWindow() {
return Commands.PROTOCOL_PREFIX + "ResizeWindow";
}
public static get kOpenWindow() {
return Commands.PROTOCOL_PREFIX + "OpenWindow";
}
public static get kCloseWindow() {
return Commands.PROTOCOL_PREFIX + "CloseWindow";
}
static _all_commands = new Set([ static _all_commands = new Set([
Commands.kUnKnowCommand, Commands.kUnKnowCommand,
Commands.kSearchDevice, Commands.kSearchDevice,
@ -52,6 +68,10 @@ export namespace Protocol {
Commands.kRpcGetWindows, Commands.kRpcGetWindows,
Commands.kRpcGetSignalSources, Commands.kRpcGetSignalSources,
Commands.kRpcGetApplicationConfig, Commands.kRpcGetApplicationConfig,
Commands.kMoveWindow,
Commands.kResizeWindow,
Commands.kOpenWindow,
Commands.kCloseWindow,
]); ]);
public static get AllCommands() { public static get AllCommands() {
@ -73,7 +93,7 @@ export namespace Protocol {
/** 是否出现异常,如果是异常,则为 ExceptionEntity */ /** 是否出现异常,如果是异常,则为 ExceptionEntity */
has_exception = false; has_exception = false;
/** 0: 请求 1: 响应 */ /** 0: 请求 1: 响应 */
flag = 0; flag = PacketEntity.FLAG_REQUEST;
/** rpc 消息 ID默认 0 */ /** rpc 消息 ID默认 0 */
rpc_id = 0; rpc_id = 0;
/** 命令 */ /** 命令 */
@ -152,11 +172,101 @@ export namespace Protocol {
} }
export class GetWindowsResponseEntity extends PacketEntity { export class GetWindowsResponseEntity extends PacketEntity {
windows: MultimediaWindowEntity[] = []; windows: WindowOpenNotifyEntity[] = [];
constructor() { constructor() {
super(); super();
this.command = Commands.kRpcGetWindows; this.command = Commands.kRpcGetWindows;
} }
} }
export class MoveWindowRequestEntity extends PacketEntity {
window_id: number = 0;
x: number = 0;
y: number = 0;
constructor(window_id: number, x: number, y: number) {
super();
this.command = Commands.kMoveWindow;
this.window_id = window_id ?? 0;
this.x = x ?? 0;
this.y = y ?? 0;
}
}
export class ResizeWindowRequestEntity extends PacketEntity {
window_id: number = 0;
width: number = 0;
height: number = 0;
constructor(window_id: number, width: number, height: number) {
super();
this.command = Commands.kResizeWindow;
this.window_id = window_id ?? 0;
this.width = width ?? 0;
this.height = height ?? 0;
}
}
export class CloseWindowRequestEntity extends PacketEntity {
window_id: number = 0;
constructor(window_id: number) {
super();
this.command = Commands.kCloseWindow;
this.window_id = window_id ?? 0;
}
}
export class OpenWindowRequestEntity extends PacketEntity {
signal_source: string = "";
x: number = 0;
y: number = 0;
width: number = 0;
height: number = 0;
constructor() {
super();
this.command = Commands.kOpenWindow;
}
}
export class WindowCloseNotifyEntity extends PacketEntity {
window_id: number = 0;
constructor() {
super();
this.command = Commands.kCloseWindow;
}
}
export class WindowOpenNotifyEntity extends PacketEntity {
window_id: number = 0;
signal_source: string = "";
x: number = 0;
y: number = 0;
width: number = 0;
height: number = 0;
constructor() {
super();
this.command = Commands.kOpenWindow;
}
}
export class WindowMoveNotifyEntity extends PacketEntity {
window_id: number = 0;
x: number = 0;
y: number = 0;
constructor() {
super();
this.command = Commands.kMoveWindow;
}
}
export class WindowResizeNotifyEntity extends PacketEntity {
window_id: number = 0;
width: number = 0;
height: number = 0;
constructor() {
super();
this.command = Commands.kResizeWindow;
}
}
} }

View File

@ -4,7 +4,7 @@
<q-page class="row items-center justify-evenly"> <q-page class="row items-center justify-evenly">
<q-card style="width: 30vw"> <q-card style="width: 30vw">
<q-card-section class="text-center text-h6"> <q-card-section class="text-center text-h6">
{{ $t('login') }} {{ $t("login") }}
</q-card-section> </q-card-section>
<q-separator /> <q-separator />
<q-card-section class="fit"> <q-card-section class="fit">
@ -90,35 +90,35 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent, reactive } from 'vue'; import { defineComponent, reactive } from "vue";
import GlobalData from 'src/common/GlobalData'; import GlobalData from "src/common/GlobalData";
import { LocalStorage, SessionStorage, useQuasar } from 'quasar'; import { LocalStorage, SessionStorage, useQuasar } from "quasar";
import ClientConnection from 'src/common/ClientConnection'; import ClientConnection from "src/common/ClientConnection";
import PermissionLevel from 'src/entities/PermissionLevel'; import PermissionLevel from "src/entities/PermissionLevel";
import { useI18n } from 'vue-i18n'; import { useI18n } from "vue-i18n";
import { useRouter } from 'vue-router'; import { useRouter } from "vue-router";
class _Data { class _Data {
user_name: string | null = null; user_name: string | null = null;
password: string | null = null; password: string | null = null;
loading = false; loading = false;
ip_address = '127.0.0.1'; ip_address = "127.0.0.1";
constructor() { constructor() {
let temp = LocalStorage.getItem('default_ip_address'); let temp = LocalStorage.getItem("default_ip_address");
if (temp) { if (temp) {
this.ip_address = temp.toString(); this.ip_address = temp.toString();
} else { } else {
this.ip_address = window.location.hostname; this.ip_address = window.location.hostname;
} }
temp = LocalStorage.getItem('default_user_name'); temp = LocalStorage.getItem("default_user_name");
if (temp) { if (temp) {
this.user_name = temp.toString(); this.user_name = temp.toString();
} }
temp = LocalStorage.getItem('default_password'); temp = LocalStorage.getItem("default_password");
if (temp) { if (temp) {
this.password = temp.toString(); this.password = temp.toString();
} }
@ -126,7 +126,7 @@ class _Data {
} }
export default defineComponent({ export default defineComponent({
name: 'PageLogin', name: "PageLogin",
components: {}, components: {},
@ -148,9 +148,9 @@ export default defineComponent({
let global_data = GlobalData.getInstance(); let global_data = GlobalData.getInstance();
let web_socket = global_data.getClient(data.ip_address); let web_socket = global_data.getClient(data.ip_address);
const url = const url =
'ws://' + "ws://" +
data.ip_address + data.ip_address +
':' + ":" +
GlobalData.kDefaultWebsocektPort.toString() + GlobalData.kDefaultWebsocektPort.toString() +
GlobalData.kWebsocketResource; GlobalData.kWebsocketResource;
if (web_socket) { if (web_socket) {
@ -166,20 +166,21 @@ export default defineComponent({
global_data.setCurrentClientName(data.ip_address); global_data.setCurrentClientName(data.ip_address);
web_socket.login_callback = (is_login) => { web_socket.login_callback = (is_login) => {
if (is_login) { if (is_login) {
SessionStorage.set('auth', PermissionLevel.Root); SessionStorage.set("auth", PermissionLevel.Root);
SessionStorage.set('url', url); SessionStorage.set("url", url);
SessionStorage.set('name', data.ip_address); SessionStorage.set("name", data.ip_address);
SessionStorage.set('user_name', data.user_name); SessionStorage.set("user_name", data.user_name);
SessionStorage.set('password', data.password); SessionStorage.set("password", data.password);
$route.push('/'); $route.push("/");
} else { } else {
$q.notify({ $q.notify({
color: 'negative', color: "negative",
icon: 'warning', icon: "warning",
message: $t.t('login fail!'), message: $t.t("login fail!"),
position: 'center', position: "center",
timeout: 1500, timeout: 1500,
}); });
SessionStorage.set("auth", PermissionLevel.None);
} }
resolve(true); resolve(true);
data.loading = false; data.loading = false;

View File

@ -7,20 +7,13 @@
@dragover="onDragOver" @dragover="onDragOver"
@drop="onDrop" @drop="onDrop"
> >
<q-popup-proxy context-menu>
<q-popup-proxy context-menu />
<q-list>
<q-item clickable v-close-popup>
<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 id="windows" style="position: absolute"> <div id="windows" style="position: absolute">
<window <window
@move_window="move_window" @reset_geometry_offset="resetGeometryOffset"
@commit_geometry="commitGeometry"
@close_this_window="closeWindow"
@close_other_windows="closeOtherWindows"
@close_all_windows="closeAllWindows"
:ref="'window_' + index" :ref="'window_' + index"
v-for="(item, index) in windows" v-for="(item, index) in windows"
:key="index" :key="index"
@ -58,24 +51,10 @@
}" }"
@resize="(evt) => loga(evt)" @resize="(evt) => loga(evt)"
> >
<q-popup-proxy context-menu no-parent-event> <q-popup-proxy context-menu>
<q-popup-proxy context-menu /> <q-popup-proxy context-menu />
<q-list> <q-list>
<q-item clickable v-close-popup> <q-item clickable v-close-popup @click="closeAllWindows">
<q-item-section avatar>
<q-icon name="close" color="red" />
</q-item-section>
<q-item-section> {{ $t("close this windwo") }} </q-item-section>
</q-item>
<q-item clickable v-close-popup>
<q-item-section avatar>
<q-icon name="close" color="red" />
</q-item-section>
<q-item-section>
{{ $t("close other windwos") }}
</q-item-section>
</q-item>
<q-item clickable v-close-popup>
<q-item-section avatar> <q-item-section avatar>
<q-icon name="close" color="red" /> <q-icon name="close" color="red" />
</q-item-section> </q-item-section>
@ -121,7 +100,7 @@ import Window from "src/components/Window.vue";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { useStore } from "src/store"; import { useStore } from "src/store";
import EventBus, { EventNamesDefine } from "src/common/EventBus"; import EventBus, { EventNamesDefine } from "src/common/EventBus";
import MultimediaWindowEntity from "src/entities/MultimediaWindowEntity"; import { WindowOpenNotifyEntity } from "src/entities/MultimediaWindowEntity";
interface _OptionsType { interface _OptionsType {
$t: any; $t: any;
@ -271,6 +250,94 @@ export default defineComponent({
calcWallVWScaler(); calcWallVWScaler();
}); });
interface _ResponseMessage {
packet: Protocol.PacketEntity;
data: string;
}
EventBus.getInstance().on(
EventNamesDefine.ResponseMessage,
(response: _ResponseMessage) => {
try {
if ((response.packet.flag = Protocol.PacketEntity.FLAG_NOTIFY)) {
switch (response.packet.command) {
case Protocol.Commands.kCloseWindow:
{
const temp = JSON.parse(response.data);
if (temp && temp.window_id) {
$store.commit("removeWindow", {
window_id: temp.window_id,
});
}
}
break;
case Protocol.Commands.kMoveWindow:
{
const temp = JSON.parse(response.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,
},
{
window,
property_name: "y",
value: temp.y ?? 0,
},
]);
}
}
}
break;
case Protocol.Commands.kResizeWindow:
{
const temp = JSON.parse(response.data);
if (temp && temp.window_id) {
const window = $store.state.windows.find(
(item) => item.window_id == temp.window_id
);
console.log(window);
if (window) {
$store.commit("setWindowPropertys", [
{
window,
property_name: "width",
value: temp.width ?? 0,
},
{
window,
property_name: "height",
value: temp.height ?? 0,
},
]);
}
}
}
break;
case Protocol.Commands.kOpenWindow:
{
const temp = JSON.parse(
response.data
) as WindowOpenNotifyEntity;
if (temp) {
$store.commit("pushWindow", temp);
}
}
break;
default:
console.log(response.packet);
break;
}
}
} catch {}
}
);
onMounted(() => { onMounted(() => {
calcWallVWScaler(); calcWallVWScaler();
}); });
@ -328,12 +395,13 @@ export default defineComponent({
onWallGridsClick(e: MouseEvent) { onWallGridsClick(e: MouseEvent) {
EventBus.getInstance().emit(EventNamesDefine.UnSelectAllWindows); EventBus.getInstance().emit(EventNamesDefine.UnSelectAllWindows);
}, },
move_window: ( resetGeometryOffset(
$store: ReturnType<typeof useStore>,
window: any, window: any,
offset_x: number, offset_x: number,
offset_y: number offset_y: number,
) => { offset_width: number,
offset_height: number
) {
$store.commit("setWindowPropertys", [ $store.commit("setWindowPropertys", [
{ {
window, window,
@ -345,8 +413,57 @@ export default defineComponent({
property_name: "y", property_name: "y",
value: window.y + offset_y * wall_height_scaler.value, value: window.y + offset_y * wall_height_scaler.value,
}, },
{
window,
property_name: "width",
value: Math.max(
window.width + offset_width * wall_height_scaler.value,
32
),
},
{
window,
property_name: "height",
value: Math.max(
window.height + offset_height * wall_height_scaler.value,
32
),
},
]); ]);
}, },
commitGeometry(window: any) {
const win = window as WindowOpenNotifyEntity;
if (win) {
GlobalData.getInstance()
.getCurrentClient()
?.moveWindow(win.window_id, win.x, win.y);
GlobalData.getInstance()
.getCurrentClient()
?.resizeWindow(win.window_id, win.width, win.height);
}
},
closeAllWindows() {
for (const window of $store.state.windows) {
if (window) {
GlobalData.getInstance()
.getCurrentClient()
?.closeWindow(window.window_id);
}
}
},
closeOtherWindows(window_id: number) {
console.log(window_id);
for (const window of $store.state.windows) {
if (window && window.window_id != window_id) {
GlobalData.getInstance()
.getCurrentClient()
?.closeWindow(window.window_id);
}
}
},
closeWindow(window_id: number) {
GlobalData.getInstance().getCurrentClient()?.closeWindow(window_id);
},
}; };
}, },
}); });

View File

@ -1,8 +1,7 @@
import { store } from "quasar/wrappers"; import { store } from "quasar/wrappers";
import MultimediaWindowEntity from "src/entities/MultimediaWindowEntity"; import { WindowOpenNotifyEntity } from "src/entities/MultimediaWindowEntity";
import { SignalSourceTreeItemEntity } from "src/entities/SignalSourceEntity"; import { SignalSourceTreeItemEntity } from "src/entities/SignalSourceEntity";
import { InjectionKey, reactive } from "vue"; import { InjectionKey, reactive } from "vue";
import { useI18n } from "vue-i18n";
import { import {
createStore, createStore,
Store as VuexStore, Store as VuexStore,
@ -31,7 +30,7 @@ export interface StateInterface {
wall_col: number; wall_col: number;
device_screen_width: number; device_screen_width: number;
device_screen_height: number; device_screen_height: number;
windows: MultimediaWindowEntity[]; windows: WindowOpenNotifyEntity[];
} }
// provide typings for `this.$store` // provide typings for `this.$store`
@ -68,9 +67,13 @@ export default store(function (/* { ssrContext } */) {
const window = item.window; const window = item.window;
const property_name = item.property_name; const property_name = item.property_name;
const value = item.value; const value = item.value;
try {
if (window && property_name) { if (window && property_name) {
window[property_name] = value; window[property_name] = value;
} }
} catch (e) {
console.log(e);
}
} }
} }
}, },
@ -82,37 +85,35 @@ export default store(function (/* { ssrContext } */) {
window[property_name] = value; window[property_name] = value;
} }
}, },
setWindows(state: StateInterface, playload?: any) { setWindows(state: StateInterface, playload?: WindowOpenNotifyEntity[]) {
let windows = playload as MultimediaWindowEntity[]; if (playload) {
if (windows) { state.windows = playload;
state.windows = windows;
} }
}, },
clearWindows(state: StateInterface, playload?: any) { clearWindows(state: StateInterface, playload?: any) {
state.windows = []; state.windows = [];
}, },
pushWindow(state: StateInterface, playload?: any) { pushWindow(state: StateInterface, playload?: WindowOpenNotifyEntity) {
const window = playload as MultimediaWindowEntity; if (playload) {
if (window) { state.windows.push(playload);
state.windows.push(window);
} }
}, },
removeWindow(state: StateInterface, playload?: any) { removeWindow(state: StateInterface, playload?: any) {
const uuid = playload.uuid; const window_id = playload.window_id;
if (uuid) { if (window_id) {
let index = state.windows.findIndex( let index = state.windows.findIndex(
(item) => item && item.uuid == uuid (item) => item && item.window_id == window_id
); );
if (index >= 0) { if (index >= 0) {
state.windows.splice(index, 1); state.windows.splice(index, 1);
} }
} else { } else {
console.log("uuid???"); console.log("window_id???");
} }
}, },
editWindow(state: StateInterface, playload?: any) { editWindow(state: StateInterface, playload?: any) {
const uuid = playload.uuid; const uuid = playload.uuid;
const new_window = playload.new_window as MultimediaWindowEntity; const new_window = playload.new_window as WindowOpenNotifyEntity;
if (uuid && new_window) { if (uuid && new_window) {
let index = state.windows.findIndex( let index = state.windows.findIndex(
(item) => item && item.uuid == uuid (item) => item && item.uuid == uuid
@ -146,10 +147,12 @@ export default store(function (/* { ssrContext } */) {
state.device_screen_height = num; state.device_screen_height = num;
} }
}, },
setSignalSourceTree(state: StateInterface, playload?: any) { setSignalSourceTree(
const item = playload as SignalSourceTreeItemEntity[]; state: StateInterface,
if (item) { playload?: SignalSourceTreeItemEntity[]
state.signal_source_tree = item; ) {
if (playload) {
state.signal_source_tree = playload;
} }
}, },
clearSignalSourceTree(state: StateInterface, playload?: any) { clearSignalSourceTree(state: StateInterface, playload?: any) {
@ -158,10 +161,12 @@ export default store(function (/* { ssrContext } */) {
// } // }
state.signal_source_tree = []; state.signal_source_tree = [];
}, },
pushSignalSourceTreeItem(state: StateInterface, playload?: any) { pushSignalSourceTreeItem(
let item = playload as SignalSourceTreeItemEntity; state: StateInterface,
if (item) { playload?: SignalSourceTreeItemEntity
state.signal_source_tree.push(item); ) {
if (playload) {
state.signal_source_tree.push(playload);
} }
}, },
buildSignalSourceTree(state: StateInterface, playload?: any) { buildSignalSourceTree(state: StateInterface, playload?: any) {