443 lines
10 KiB
Vue
443 lines
10 KiB
Vue
<template>
|
|
<div
|
|
class="window_class window_flag"
|
|
:class="
|
|
(selected ? 'window_selected' : 'window_normal') +
|
|
' ' +
|
|
(focused ? 'top' : '')
|
|
"
|
|
@click="onClick"
|
|
@mousedown="onMouseDown"
|
|
@mousemove="onMouseMove"
|
|
@mouseleave="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">
|
|
<q-icon :name="getItemIcon(signal_source.window_type)" />
|
|
<span>{{ signal_source.name }}</span>
|
|
</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>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.window_class {
|
|
}
|
|
|
|
.window_flag {
|
|
}
|
|
|
|
.window_selected {
|
|
outline-style: dashed;
|
|
outline-color: #166fab;
|
|
}
|
|
|
|
.window_normal {
|
|
border: 1px solid #166fab;
|
|
}
|
|
|
|
.title_bar {
|
|
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>
|
|
|
|
<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 } from "vue";
|
|
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({
|
|
name: "ComponentWindow",
|
|
|
|
components: {},
|
|
props: {
|
|
signal_source_table_uuid: {
|
|
type: String,
|
|
required: true,
|
|
},
|
|
window: {
|
|
type: Object,
|
|
required: true,
|
|
},
|
|
},
|
|
emits: [
|
|
"reset_geometry_offset",
|
|
"commit_geometry",
|
|
"close_this_window",
|
|
"close_other_windows",
|
|
"close_all_windows",
|
|
"window_fouse_in",
|
|
],
|
|
setup(props, { emit }) {
|
|
const $store = useStore();
|
|
|
|
const signal_source = ref(
|
|
GlobalData.getInstance().getSignalSource(props.signal_source_table_uuid)
|
|
);
|
|
|
|
let selected = ref(false);
|
|
let focused = ref(false);
|
|
let can_move = ref(true);
|
|
let can_resize = ref(true);
|
|
|
|
const onUnSelectAllWindows = () => {
|
|
selected.value = false;
|
|
focused.value = false;
|
|
};
|
|
|
|
const onUnFocusAllWindows = () => {
|
|
focused.value = false;
|
|
};
|
|
|
|
EventBus.getInstance().on(
|
|
EventNamesDefine.UnSelectAllWindows,
|
|
onUnSelectAllWindows
|
|
);
|
|
|
|
EventBus.getInstance().on(
|
|
EventNamesDefine.UnFocusAllWindows,
|
|
onUnFocusAllWindows
|
|
);
|
|
|
|
onUnmounted(() => {
|
|
EventBus.getInstance().removeListener(
|
|
EventNamesDefine.UnSelectAllWindows,
|
|
onUnSelectAllWindows
|
|
);
|
|
});
|
|
|
|
watch(
|
|
() => props.window.window_state,
|
|
(newValue, oldValue) => {
|
|
if (newValue) {
|
|
let old = selected.value;
|
|
if (newValue.focus) {
|
|
EventBus.getInstance().emit(EventNamesDefine.UnFocusAllWindows);
|
|
}
|
|
focused.value = newValue.focus;
|
|
selected.value = old;
|
|
}
|
|
}
|
|
);
|
|
|
|
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;
|
|
};
|
|
|
|
const flags = new _Flags();
|
|
|
|
return {
|
|
signal_source,
|
|
selected,
|
|
focused,
|
|
can_move,
|
|
can_resize,
|
|
flags,
|
|
|
|
onClick(evt: PointerEvent) {
|
|
if (selected.value != true) {
|
|
EventBus.getInstance().emit(EventNamesDefine.UnSelectAllWindows);
|
|
selected.value = true;
|
|
focused.value = true;
|
|
emit("window_fouse_in", props.window.window_id);
|
|
}
|
|
},
|
|
onMouseDown(evt: MouseEvent) {
|
|
if (selected.value) {
|
|
if (evt.button == 0) {
|
|
mouse_down_flag = true;
|
|
mouse_last_pos_x = evt.x;
|
|
mouse_last_pos_y = evt.y;
|
|
}
|
|
}
|
|
},
|
|
onMouseMove(evt: MouseEvent) {
|
|
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;
|
|
}
|
|
},
|
|
|
|
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;
|
|
}
|
|
},
|
|
|
|
cleanMouseDownFlag,
|
|
onMouseLeave(evt: MouseEvent) {
|
|
if (selected.value && mouse_down_flag) {
|
|
cleanMouseDownFlag();
|
|
emit("commit_geometry", props.window);
|
|
}
|
|
},
|
|
|
|
onMouseUp(evt: MouseEvent) {
|
|
if (selected.value && mouse_down_flag) {
|
|
cleanMouseDownFlag();
|
|
emit("commit_geometry", props.window);
|
|
}
|
|
|
|
if (!focused) {
|
|
emit("window_fouse_in", props.window.window_id);
|
|
}
|
|
},
|
|
|
|
getItemIcon(item_type: string) {
|
|
return Common.getSignalSourceIcon(item_type);
|
|
},
|
|
};
|
|
},
|
|
});
|
|
</script>
|