完成平板的窗口移动,大小调整,双击铺满功能

This commit is contained in:
fangxiang 2022-04-15 15:39:10 +08:00
parent c76d964ffd
commit 509fed80d4
7 changed files with 659 additions and 63 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 451 B

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -13,7 +13,6 @@ export default defineComponent({
setup() {
let $q = useQuasar();
let $router = useRouter();
console.log($q.platform);
if (
($q.platform.is.mobile && $q.platform.has.touch) ||
$q.platform.is.ipad

View File

@ -8,6 +8,7 @@
"
@mousedown="onMouseDown"
@click="onClick"
@touchend="onTouchEnd"
:style="{
background: $props.window.client_color,
}"
@ -132,6 +133,7 @@
</q-item-section>
</q-item>
<q-item
v-if="show_pollong_setting_context_menu"
clickable
v-close-popup
:disable="$props.disable || $props.window.polling"
@ -212,13 +214,10 @@
<script lang="ts">
import { Common } from "src/common/Common";
import EventBus, { EventNamesDefine } from "src/common/EventBus";
import GlobalData from "src/common/GlobalData";
import { defineComponent, ref, watch, onUnmounted, computed } from "vue";
import { defineComponent, ref, watch, computed, getCurrentInstance } from "vue";
import { useStore } from "src/store";
import { SignalSourceEntity } from "src/entities/SignalSourceEntity";
import { NotifyMessage } from "src/common/ClientConnection";
import { Protocol } from "src/entities/WSProtocol";
class _Flags {
get up_flag() {
@ -257,6 +256,10 @@ export default defineComponent({
plan_running: {
type: Boolean,
},
show_pollong_setting_context_menu: {
type: Boolean,
default: false,
},
},
emits: [
"close_this_window",
@ -270,6 +273,7 @@ export default defineComponent({
"stop_polling",
"start_polling",
"polling_setting",
"dbtouch",
],
setup(props, { emit }) {
const $store = useStore();
@ -310,6 +314,27 @@ export default defineComponent({
const flags = new _Flags();
let ctrl_press_flag = false;
let prev_touch_time = 0;
const onclick = (evt: UIEvent) => {
if (props.plan_running) {
return;
}
if (ctrl_press_flag) {
ctrl_press_flag = false;
return;
}
if (!props.mouse_area_flag) {
// evt.stopPropagation();
if (props.window.uuid != $store.state.selected_window) {
GlobalData.getInstance()
.getCurrentClient()
?.focusIn(props.window.window_id);
}
$store.commit("setSelectedWindow", props.window.uuid);
}
};
return {
signal_source,
flags,
@ -322,24 +347,23 @@ export default defineComponent({
ctrl_press_flag = true;
}
},
onClick(evt: MouseEvent) {
if (props.plan_running) {
return;
}
if (ctrl_press_flag) {
ctrl_press_flag = false;
return;
}
if (!props.mouse_area_flag) {
evt.stopPropagation();
if (props.window.uuid != $store.state.selected_window) {
GlobalData.getInstance()
.getCurrentClient()
?.focusIn(props.window.window_id);
onTouchEnd(evt: TouchEvent) {
if ((<any>window).touchPriority) {
let time = Date.now();
if (time - prev_touch_time < 300) {
emit("dbtouch");
} else {
onclick(evt);
}
$store.commit("setSelectedWindow", props.window.uuid);
prev_touch_time = time;
}
},
onClick(evt: MouseEvent) {
if ((<any>window).touchPriority) {
return;
}
onclick(evt);
},
getItemIcon(item_type: string) {
return Common.getSignalSourceIcon(item_type);

View File

@ -9,21 +9,21 @@
width: wall_width + 'px',
height: wall_height + 'px',
}"
class="wall"
class="wall_content"
>
<div id="windows" style="position: absolute">
<vue3-resize-drag
:w="item.width * ($refs.wall?.clientWidth ?? 0)"
:h="item.height * ($refs.wall?.clientHeight ?? 0)"
:w="item.width * ($refs.wall_content?.clientWidth ?? 0)"
:h="item.height * ($refs.wall_content?.clientHeight ?? 0)"
:x="
($refs.wall?.parentElement?.offsetLeft ?? 0) +
($refs.wall?.offsetLeft ?? 0) +
item.x * ($refs.wall?.clientWidth ?? 0)
$refs.wall?.parentElement?.offsetLeft +
$refs.wall_content?.offsetLeft +
item.x * ($refs.wall_content?.clientWidth ?? 0)
"
:y="
($refs.wall?.parentElement?.offsetTop ?? 0) +
($refs.wall?.offsetTop ?? 0) +
item.y * ($refs.wall?.clientHeight ?? 0)
$refs.wall?.parentElement?.offsetTop +
$refs.wall_content?.offsetTop +
item.y * ($refs.wall_content?.clientHeight ?? 0)
"
:zIndex="
$store.state.windows_sort.findIndex(
@ -33,7 +33,7 @@
:isActive="item.uuid == $store.state.selected_window"
:resizeIconSize="14"
:isGuide="true"
v-for="(item, index) in $store.state.windows"
v-for="(item, index) in windows"
:key="index"
@resizeEndHandler="resizeWindow(item.window_id, $event)"
@moveEndHandler="moveWindow(item.window_id, $event)"
@ -46,12 +46,10 @@
@replace_this_window="repliceWindow"
@top_window="topWindow"
@lower_window="lowerWindow"
@dblclick="(evt) => windowDBClick(item.window_id)"
@edit_volume="edit_volume"
@dbtouch="(evt) => windowDBClick(item.window_id)"
@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"
@ -65,7 +63,10 @@
</window>
</vue3-resize-drag>
</div>
<div ref="wall_grids">
<div
ref="wall_grids"
@touchstart="$store.commit('setSelectedWindow', '')"
>
<div
v-for="row in wall_rows"
:key="row"
@ -80,19 +81,11 @@
:key="col"
class="col wall_item wall_item_flag"
:style="{
width: cell_witdh + 'px',
width: cell_width + 'px',
height: cell_height + 'px',
}"
>
<q-popup-proxy
context-menu
@show="
{
//last_context_menu_pos_x = $event.layerX;
//last_context_menu_pos_y = $event.layerY;
}
"
>
<q-popup-proxy context-menu @show="onContextMenuShow($event)">
<q-list>
<q-item
:disable="plan_running"
@ -125,10 +118,11 @@
</div>
</div>
</div>
<file-manage-dialog ref="file_manage_dialog" />
</template>
<style scoped>
.wall {
.wall_content {
border: 1px solid black;
}
@ -158,16 +152,45 @@ const elementResizeDetectorMaker = require("element-resize-detector");
import vue3ResizeDrag from "../third_lib/vue3-resize-drag/components/vue3-resize-drag/index.vue";
import Window from "src/components/Window.vue";
import GlobalData from "src/common/GlobalData";
import FileEntity from "src/entities/FileEntity";
import { SignalSourceEntity } from "src/entities/SignalSourceEntity";
import { Protocol } from "src/entities/WSProtocol";
import FileManageDialog from "src/components/FileManageDialog.vue";
import WindowOtherStateChangeNotifyEntity from "src/entities/WindowOtherStateChangeNotifyEntity";
import { WindowOpenNotifyEntity } from "src/entities/MultimediaWindowEntity";
import { NotifyMessage } from "src/common/ClientConnection";
import EventBus, { EventNamesDefine } from "src/common/EventBus";
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: "PadContentWallPage",
components: { Window, vue3ResizeDrag },
components: { FileManageDialog, Window, vue3ResizeDrag },
setup() {
const $store = useStore();
const $q = useQuasar();
const $t = useI18n();
const last_context_menu_pos_y = ref(0);
const last_context_menu_pos_x = ref(0);
const wall: Ref<any> = ref(null);
const wall_content: Ref<any> = ref(null);
const file_manage_dialog: Ref<any> = ref(null);
const wall_width = ref(0);
const wall_height = ref(0);
@ -184,6 +207,237 @@ export default defineComponent({
const cell_width = ref(0);
const cell_height = 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 area_open_window_flag = ref(false);
const area_open_window_rect = ref(new Rect());
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) {
$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 && wall.value.parentElement) {
const wall_parent = wall.value.parentElement as HTMLElement;
@ -201,8 +455,6 @@ export default defineComponent({
height = width * 0.56;
}
console.log(height);
console.log(width);
wall_height.value = height;
wall_width.value = width;
@ -217,18 +469,328 @@ export default defineComponent({
}
});
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_content.value.offsetLeft;
const y =
rect.top -
(wall.value.parentElement?.offsetTop ?? 0) -
wall_content.value.offsetTop;
GlobalData.getInstance()
.getCurrentClient()
?.moveWindow(
window_id,
x / wall_content.value.clientWidth,
y / wall_content.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;
// moveWindow(window_id, evt);
if (wall.value) {
// GlobalData.getInstance()
// .getCurrentClient()
// ?.resizeWindow(
// window_id,
// evt.width / wall.value.clientWidth,
// evt.height / wall.value.clientHeight
// );
const x =
rect.left -
(wall.value.parentElement?.offsetLeft ?? 0) -
wall_content.value.offsetLeft;
const y =
rect.top -
(wall.value.parentElement?.offsetTop ?? 0) -
wall_content.value.offsetTop;
GlobalData.getInstance()
.getCurrentClient()
?.setWindowGeometry(
window_id,
x / wall_content.value.clientWidth,
y / wall_content.value.clientHeight,
rect.width / wall_content.value.clientWidth,
rect.height / wall_content.value.clientHeight
);
}
};
return {
wall,
file_manage_dialog,
wall_width,
wall_height,
wall_rows,
wall_cols,
cell_width,
cell_height,
plan_running,
area_open_window_flag,
area_open_window_rect,
last_context_menu_pos_x,
last_context_menu_pos_y,
windows,
wall_content,
// functions
moveWindow,
resizeWindow,
loga(a: any) {
console.log(a);
},
mute_unmute(window_id: number) {
const window = $store.state.windows.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 = $store.state.windows.find(
(element) => element && element.window_id == window_id
);
if (window) {
GlobalData.getInstance().getCurrentClient()?.startPolling(window_id);
}
},
stop_polling(window_id: number) {
const window = $store.state.windows.find(
(element) => element && element.window_id == window_id
);
if (window) {
GlobalData.getInstance().getCurrentClient()?.stopPolling(window_id);
}
},
topWindow(window_id: number) {
GlobalData.getInstance().getCurrentClient()?.focusIn(window_id);
},
lowerWindow(window_id: number) {
GlobalData.getInstance().getCurrentClient()?.lowerWindow(window_id);
},
windowDBClick(window_id: number) {
if (plan_running.value) {
return;
}
GlobalData.getInstance().getCurrentClient()?.windowFitGrid(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);
}
}
},
closeWindow(window_id: number) {
GlobalData.getInstance().getCurrentClient()?.closeWindow(window_id);
},
closeAllWindows() {
// for (const window of $store.state.windows) {
// if (window) {
// GlobalData.getInstance()
// .getCurrentClient()
// ?.closeWindow(window.window_id);
// }
// }
GlobalData.getInstance().getCurrentClient()?.closeWindow(-1);
},
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;.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")
) {
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 {}
}
}
}
}
},
onContextMenuShow(event: TouchEvent) {
if (event && event.changedTouches && event.changedTouches.length) {
last_context_menu_pos_x.value = event.changedTouches[0].pageX;
last_context_menu_pos_y.value = event.changedTouches[0].pageY;
console.log(event.changedTouches[0]);
console.log(
last_context_menu_pos_x.value -
(wall.value.parentElement?.offsetLeft ?? 0) -
wall_content.value.offsetLeft
);
console.log(
last_context_menu_pos_y.value -
(wall.value.parentElement?.offsetTop ?? 0) -
wall_content.value.offsetTop
);
}
},
async openWindowByLocalFile(event: MouseEvent) {
if (!wall.value) {
return;
}
const obj = await file_manage_dialog.value.showDialogAsync(
"select",
".mp4;.avi;.ts;.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")
) {
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;
console.log(last_context_menu_pos_x);
console.log(last_context_menu_pos_y);
const col = Math.floor(
(last_context_menu_pos_x.value -
(wall.value.parentElement?.offsetLeft ?? 0) -
wall_content.value.offsetLeft) /
wall_content.value.offsetWidth /
cell_width
);
const row = Math.floor(
(last_context_menu_pos_y.value -
(wall.value.parentElement?.offsetTop ?? 0) -
wall_content.value.offsetTop) /
wall_content.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 {}
}
}
},
};
},
});

View File

@ -89,6 +89,8 @@ export default defineComponent({
setup() {
const show_back = ref(true);
(<any>window).isPad = true; // pad flag
(<any>window).touchPriority = true // 使
setCssVar('primary', '#0b3536')
setCssVar('secondary', '#ffffff')

View File

@ -156,7 +156,6 @@ export default defineComponent({
);
if (window) {
selected_window.value = window;
console.log(window);
const signal_source = GlobalData.getInstance().signal_source.find(
(element) =>
element && element.uuid == window.signal_source_table_uuid

View File

@ -55,6 +55,7 @@
: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>
@ -611,16 +612,25 @@ export default defineComponent({
}
});
const moveWindow = (window_id: number, evt: any) => {
evt.x = evt.x ?? 0;
evt.y = evt.y ?? 0;
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 =
evt.left -
rect.left -
(wall.value.parentElement?.offsetLeft ?? 0) -
wall.value.offsetLeft;
const y =
evt.top -
rect.top -
(wall.value.parentElement?.offsetTop ?? 0) -
wall.value.offsetTop;
GlobalData.getInstance()
@ -633,11 +643,11 @@ export default defineComponent({
}
};
const resizeWindow = (window_id: number, evt: any) => {
evt.width = evt.width ?? 0;
evt.height = evt.height ?? 0;
evt.left = evt.left ?? 0;
evt.top = evt.top ?? 0;
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;
// moveWindow(window_id, evt);
if (wall.value) {
// GlobalData.getInstance()
@ -648,11 +658,11 @@ export default defineComponent({
// evt.height / wall.value.clientHeight
// );
const x =
evt.left -
rect.left -
(wall.value.parentElement?.offsetLeft ?? 0) -
wall.value.offsetLeft;
const y =
evt.top -
rect.top -
(wall.value.parentElement?.offsetTop ?? 0) -
wall.value.offsetTop;
GlobalData.getInstance()
@ -661,8 +671,8 @@ export default defineComponent({
window_id,
x / wall.value.clientWidth,
y / wall.value.clientHeight,
evt.width / wall.value.clientWidth,
evt.height / wall.value.clientHeight
rect.width / wall.value.clientWidth,
rect.height / wall.value.clientHeight
);
}
};