重构虚拟窗口移动,调整大小逻辑

This commit is contained in:
fangxiang 2022-02-12 10:16:08 +08:00
parent bfc271db2d
commit e1b1ec4ee7
18 changed files with 1426 additions and 736 deletions

View File

@ -14,20 +14,20 @@
"@types/element-resize-detector": "^1.1.3",
"autoprefixer": "^10.4.2",
"axios": "^0.21.1",
"core-js": "^3.6.5",
"element-resize-detector": "^1.2.3",
"quasar": "^2.5.4",
"core-js": "^3.21.0",
"element-resize-detector": "^1.2.4",
"quasar": "^2.5.5",
"reconnecting-websocket": "^4.4.0",
"v-viewer": "^3.0.9",
"vue": "^3.0.0",
"vue-i18n": "^9.0.0-beta.0",
"vue-i18n": "^9.1.9",
"vue-router": "^4.0.0",
"vuex": "^4.0.1"
},
"devDependencies": {
"@quasar/app": "^3.3.2",
"@quasar/app": "^3.3.3",
"@types/node": "^10.17.15",
"workbox-webpack-plugin": "^6.0.0"
"workbox-webpack-plugin": "^6.4.2"
},
"browserslist": [
"last 10 Chrome versions",

View File

@ -493,6 +493,26 @@ export default class ClientConnection {
);
}
public setWindowGeometry(
window_id: number,
x: number,
y: number,
width: number,
height: number
) {
this.ws?.send(
JSON.stringify(
new Protocol.SetWindowGeometryRequestEntity(
window_id,
x,
y,
width,
height
)
)
);
}
public closeWindow(window_id: number) {
this.ws?.send(
JSON.stringify(new Protocol.CloseWindowRequestEntity(window_id))

View File

@ -18,7 +18,6 @@ export default class EventBus extends EventEmitter {
export namespace EventNamesDefine {
export const UnKnow = "onUnKnow";
export const UnSelectAllWindows = "onUnSelectAllWindows";
export const WindowResize = "onWindowResize";
export const WindowMouseDown = "onWindowMouseDown";
export const WindowMouseMove = "onWindowMouseMove";

View File

@ -1,12 +1,12 @@
<template>
<div
class="window_class window_flag"
:class="selected ? 'window_selected' : 'window_normal'"
:class="
$props.window.uuid == $store.state.selected_window
? 'window_selected'
: 'window_normal'
"
@click="onClick"
@mousedown="onMouseDown"
@mousemove="onMouseMove"
@mouseleave="onMouseLeave"
@mouseup="onMouseUp"
:style="{
background: $props.window.client_color,
}"
@ -154,87 +154,6 @@
}}</q-tooltip>
</div>
</div>
<div
v-if="!$props.disable && 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="!$props.disable && 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="!$props.disable && 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="!$props.disable && 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="!$props.disable && 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="!$props.disable && 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="!$props.disable && 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="!$props.disable && 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>
</template>
@ -261,81 +180,6 @@
.top {
z-index: 1;
}
.resize_div {
background: gray;
width: 32px;
height: 32px;
z-index: 999;
}
.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>
<script lang="ts">
@ -382,8 +226,6 @@ export default defineComponent({
},
},
emits: [
"reset_geometry_offset",
"commit_geometry",
"close_this_window",
"close_other_windows",
"close_all_windows",
@ -423,56 +265,13 @@ export default defineComponent({
return signal_source.value.window_type == "EwindowType::Clock";
});
let selected = ref(false);
let can_move = ref(true);
let can_resize = ref(true);
let move_flag = false;
const onUnSelectAllWindows = () => {
selected.value = false;
};
EventBus.getInstance().on(
EventNamesDefine.UnSelectAllWindows,
onUnSelectAllWindows
);
onUnmounted(() => {
EventBus.getInstance().removeListener(
EventNamesDefine.UnSelectAllWindows,
onUnSelectAllWindows
);
});
let mouse_down_flag = false;
let mouse_last_pos_x = 0;
let mouse_last_pos_y = 0;
const cleanMouseDownFlag = () => {
mouse_down_flag = false;
mouse_last_pos_x = 0;
mouse_last_pos_y = 0;
move_flag = false;
};
reload_signal_source();
watch(
() => props.window,
(a, b) => {
reload_signal_source();
selected.value = false;
cleanMouseDownFlag();
}
);
const flags = new _Flags();
let ctrl_press_flag = false;
return {
signal_source,
selected,
can_move,
can_resize,
flags,
is_audo_player_window,
is_clock_window,
@ -485,112 +284,7 @@ export default defineComponent({
}
if (!props.mouse_area_flag) {
evt.stopPropagation();
if (selected.value != true) {
EventBus.getInstance().emit(EventNamesDefine.UnSelectAllWindows);
selected.value = true;
$store.commit("setSelectedWindow", props.window.uuid);
}
}
},
onMouseDown(evt: MouseEvent) {
ctrl_press_flag = evt.ctrlKey;
if (!evt.ctrlKey) {
evt.stopPropagation();
if (props.disable) {
return;
}
if (selected.value) {
if (evt.button == 0) {
mouse_down_flag = true;
mouse_last_pos_x = evt.x;
mouse_last_pos_y = evt.y;
}
}
}
// console.log("down", ctrl_flag);
},
onMouseMove(evt: MouseEvent) {
if (!props.mouse_area_flag) {
evt.stopPropagation();
if (can_move.value && mouse_down_flag && selected.value) {
emit(
"reset_geometry_offset",
props.window,
evt.x - mouse_last_pos_x,
evt.y - mouse_last_pos_y,
0,
0
);
mouse_last_pos_x = evt.x;
mouse_last_pos_y = evt.y;
move_flag = true;
}
}
},
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_y = evt.y;
move_flag = true;
}
},
cleanMouseDownFlag,
onMouseLeave(evt: MouseEvent) {
ctrl_press_flag = false;
if (!props.mouse_area_flag) {
if (selected.value && mouse_down_flag) {
if (move_flag) {
emit("commit_geometry", props.window);
}
cleanMouseDownFlag();
}
}
},
onMouseUp(evt: MouseEvent) {
// console.log("up", ctrl_flag);
if (selected.value && mouse_down_flag) {
if (move_flag) {
emit("commit_geometry", props.window);
}
cleanMouseDownFlag();
$store.commit("setSelectedWindow", props.window.uuid);
}
},

View File

@ -60,6 +60,9 @@ export namespace Protocol {
return Commands.PROTOCOL_PREFIX + "ResizeWindow";
}
public static get kSetWindowGeometry() {
return Commands.PROTOCOL_PREFIX + "SetWindowGeometry";
}
public static get kOpenWindow() {
return Commands.PROTOCOL_PREFIX + "OpenWindow";
}
@ -289,6 +292,7 @@ export namespace Protocol {
Commands.kRpcGetApplicationConfig,
Commands.kMoveWindow,
Commands.kResizeWindow,
Commands.kSetWindowGeometry,
Commands.kOpenWindow,
Commands.kCloseWindow,
Commands.kTopWindow,
@ -521,6 +525,29 @@ export namespace Protocol {
}
}
export class SetWindowGeometryRequestEntity extends PacketEntity {
window_id: number = 0;
x: number = 0;
y: number = 0;
width: number = 0;
height: number = 0;
constructor(
window_id: number,
x: number,
y: number,
width: number,
height: number
) {
super();
this.command = Commands.kSetWindowGeometry;
this.window_id = window_id ?? 0;
this.x = x ?? 0;
this.y = y ?? 0;
this.width = width ?? 0;
this.height = height ?? 0;
}
}
export class CloseWindowRequestEntity extends PacketEntity {
window_id: number = 0;
constructor(window_id: number) {

View File

@ -9,51 +9,53 @@
style="background-color: #bce0f0"
>
<div id="windows" style="position: absolute">
<window
@reset_geometry_offset="resetGeometryOffset"
@commit_geometry="commitGeometry"
@close_this_window="closeWindow"
@close_other_windows="closeOtherWindows"
@close_all_windows="closeAllWindows"
@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"
<vue3-resize-drag
:w="item.width * $refs.wall.clientWidth"
:h="item.height * $refs.wall.clientHeight"
:x="
($refs.wall.parentElement?.offsetLeft ?? 0) +
$refs.wall.offsetLeft +
item.x * $refs.wall.clientWidth
"
:y="
($refs.wall.parentElement?.offsetTop ?? 0) +
$refs.wall.offsetTop +
item.y * $refs.wall.clientHeight
"
:zIndex="
$store.state.windows_sort.findIndex((element) => element == item.uuid)
"
:isActive="item.uuid == $store.state.selected_window"
:isGuide="true"
v-for="(item, index) in windows"
:key="index"
:ref="'window_' + item.window_id"
:id="'window_' + item.window_id"
:uuid="item.uuid"
:disable="plan_running"
class="window"
:mouse_area_flag="area_open_window_flag"
:signal_source_table_uuid="item.signal_source_table_uuid"
:window="item"
:style="{
top:
(item.y * $store.state.device_screen_height) / wall_height_scaler +
'px',
left:
(item.x * $store.state.device_screen_width) / wall_width_scaler +
'px',
width:
(item.width * $store.state.device_screen_width) /
wall_width_scaler +
'px',
height:
(item.height * $store.state.device_screen_height) /
wall_height_scaler +
'px',
'z-index': $store.state.windows_sort.findIndex(
(element) => element == item.uuid
),
}"
style="background: red; position: fixed"
@resizeEndHandler="resizeWindow(item.window_id, $event)"
@moveEndHandler="moveWindow(item.window_id, $event)"
>
</window>
<window
@close_this_window="closeWindow"
@close_other_windows="closeOtherWindows"
@close_all_windows="closeAllWindows"
@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"
:ref="'window_' + item.window_id"
:id="'window_' + item.window_id"
:uuid="item.uuid"
:disable="plan_running"
class="window fit"
:mouse_area_flag="area_open_window_flag"
:signal_source_table_uuid="item.signal_source_table_uuid"
:window="item"
>
</window>
</vue3-resize-drag>
</div>
<div ref="wall_grids" @click="onWallGridsClick">
<div
@ -157,6 +159,8 @@ 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";
class Rect {
start_x = 0;
start_y = 0;
@ -174,7 +178,12 @@ class Rect {
export default defineComponent({
name: "PageWall",
components: { Window, EditVolumeDialog, PollingSettingDialog },
components: {
vue3ResizeDrag,
Window,
EditVolumeDialog,
PollingSettingDialog,
},
setup() {
const $q = useQuasar();
const $store = useStore();
@ -208,17 +217,6 @@ export default defineComponent({
let item_witdh = ref(0);
const item_height = ref(0);
const wall_width_scaler = ref(0);
const wall_height_scaler = ref(0);
const calcWallVWScaler = (wall_width: number, wall_height: number) => {
if (wall.value && wall.value.parentElement) {
wall_height_scaler.value =
$store.state.device_screen_height / wall_height;
wall_width_scaler.value = $store.state.device_screen_width / wall_width;
}
};
const calcWallItemWH = () => {
item_witdh.value =
wall?.value?.parentElement?.offsetWidth ?? 0 / wall_cols.value;
@ -302,14 +300,10 @@ export default defineComponent({
?.openWindow(
new Protocol.OpenWindowRequestEntity(
$store.state.selected_signal_source,
(start_x * wall_width_scaler.value) /
$store.state.device_screen_width,
(start_y * wall_height_scaler.value) /
$store.state.device_screen_height,
(end_x * wall_width_scaler.value) /
$store.state.device_screen_width,
(end_y * wall_height_scaler.value) /
$store.state.device_screen_height
start_x / wall.value.offsetWidth,
start_y / wall.value.offsetHeight,
end_x / wall.value.offsetWidth,
end_y / wall.value.offsetHeight
)
);
}
@ -367,12 +361,14 @@ export default defineComponent({
}
}
if (!flag) {
EventBus.getInstance().emit(EventNamesDefine.UnSelectAllWindows);
$store.commit("setSelectedWindow", "");
}
}
}
);
const __temp__size_a__ = 0.00000001;
EventBus.getInstance().on(
EventNamesDefine.NotifyMessage,
(notify: NotifyMessage) => {
@ -396,18 +392,34 @@ export default defineComponent({
(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,
},
]);
// ,
// $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);
}
}
}
@ -420,18 +432,33 @@ export default defineComponent({
(item) => item.window_id == temp.window_id
);
if (window) {
$store.commit("setWindowPropertys", [
{
window,
property_name: "width",
value: temp.width ?? 0,
},
{
window,
property_name: "height",
value: temp.height ?? 0,
},
]);
// $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);
}
}
}
@ -554,13 +581,69 @@ export default defineComponent({
(element: HTMLElement) => {
if (element) {
calcWallItemWH();
calcWallVWScaler(element.offsetWidth, element.offsetHeight);
}
}
);
}
});
const moveWindow = (window_id: number, evt: any) => {
evt.x = evt.x ?? 0;
evt.y = evt.y ?? 0;
if (wall.value) {
const x =
evt.left -
(wall.value.parentElement?.offsetLeft ?? 0) -
wall.value.offsetLeft;
const y =
evt.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, evt: any) => {
console.log(evt);
evt.width = evt.width ?? 0;
evt.height = evt.height ?? 0;
evt.left = evt.left ?? 0;
evt.top = evt.top ?? 0;
// moveWindow(window_id, evt);
if (wall.value) {
// GlobalData.getInstance()
// .getCurrentClient()
// ?.resizeWindow(
// window_id,
// evt.width / wall.value.clientWidth,
// evt.height / wall.value.clientHeight
// );