feat(KeySwipe): add swipe key setting

This commit is contained in:
AkiChase 2024-05-31 18:05:03 +08:00
parent 996bc2517b
commit fbbdb1b4b8
7 changed files with 411 additions and 22 deletions

View File

@ -63,16 +63,6 @@ let deviceWaitForScreenSizeTask: ((w: number, h: number) => void) | null = null;
let unlisten: UnlistenFn | undefined;
let lastClipboard = "";
// TODO swipe
//
// 1. 使svgpolylinegptvue线
// 2. 使svgcircle
//
// 1.
// 2. 使svg线
// 3.
// 4.
onMounted(async () => {
unlisten = await listen("device-reply", (event) => {
try {

View File

@ -8,6 +8,7 @@ import KeySkill from "./KeySkill.vue";
import KeyObservation from "./KeyObservation.vue";
import KeySight from "./KeySight.vue";
import KeyFire from "./KeyFire.vue";
import KeySwipe from "./KeySwipe.vue";
import ScreenStream from "../ScreenStream.vue";
import {
@ -17,6 +18,7 @@ import {
KeyTap,
KeyMacro,
KeyMapping,
KeySwipe as KeyMappingKeySwipe,
KeySight as KeyMappingKeySight,
KeyFire as KeyMappingKeyFire,
} from "../../keyMappingConfig";
@ -43,6 +45,10 @@ const addButtonOptions: DropdownOption[] = [
label: () => t("pages.KeyBoard.addButton.SteeringWheel"),
key: "SteeringWheel",
},
{
label: () => t("pages.KeyBoard.addButton.Swipe"),
key: "Swipe",
},
{
label: () => t("pages.KeyBoard.addButton.Skill"),
key: "DirectionalSkill",
@ -72,6 +78,7 @@ const addButtonOptions: DropdownOption[] = [
function onAddButtonSelect(
type:
| "Tap"
| "Swipe"
| "SteeringWheel"
| "DirectionalSkill"
| "CancelSkill"
@ -92,6 +99,12 @@ function onAddButtonSelect(
if (type === "Tap") {
keyMapping.pointerId = 3;
(keyMapping as KeyTap).time = 80;
} else if (type === "Swipe") {
keyMapping.pointerId = 3;
(keyMapping as KeyMappingKeySwipe).pos = [
{ x: keyMapping.posX, y: keyMapping.posY },
];
(keyMapping as KeyMappingKeySwipe).intervalBetweenPos = 0;
} else if (type === "SteeringWheel") {
keyMapping.pointerId = 1;
(keyMapping as unknown as KeyMappingSteeringWheel).key = {
@ -173,6 +186,7 @@ function setCurButtonKey(curKey: string) {
keyboardStore.showButtonSettingFlag ||
keyboardStore.activeButtonIndex >= store.editKeyMappingList.length ||
keyboardStore.showButtonSettingFlag ||
keyboardStore.editSwipePointsFlag ||
keyboardStore.showButtonAddFlag
)
return;
@ -363,6 +377,10 @@ onBeforeRouteLeave(() => {
v-else-if="store.editKeyMappingList[index].type === 'Observation'"
:index="index"
/>
<KeySwipe
v-else-if="store.editKeyMappingList[index].type === 'Swipe'"
:index="index"
/>
<KeySight
v-else-if="store.editKeyMappingList[index].type === 'Sight'"
:index="index"

View File

@ -1,5 +1,5 @@
<script setup lang="ts">
import { Settings, CloseCircle } from "@vicons/ionicons5";
import { Settings, CloseCircle, ReturnUpBack } from "@vicons/ionicons5";
import {
NButton,
NIcon,
@ -122,14 +122,18 @@ function dragHandler(downEvent: MouseEvent) {
localStore.set("keySettingPos", keySettingPos.value);
} else {
// click up
keyboardStore.activeButtonIndex = -1;
keyboardStore.activeSteeringWheelButtonKeyIndex = -1;
keyboardStore.showSettingFlag = !keyboardStore.showSettingFlag;
if (
keyboardStore.showSettingFlag &&
store.keyMappingConfigList.length === 1
) {
message.info(t("pages.KeyBoard.KeySetting.onlyOneConfig"));
if (keyboardStore.editSwipePointsFlag) {
keyboardStore.editSwipePointsFlag = false;
} else {
keyboardStore.activeButtonIndex = -1;
keyboardStore.activeSteeringWheelButtonKeyIndex = -1;
keyboardStore.showSettingFlag = !keyboardStore.showSettingFlag;
if (
keyboardStore.showSettingFlag &&
store.keyMappingConfigList.length === 1
) {
message.info(t("pages.KeyBoard.KeySetting.onlyOneConfig"));
}
}
}
};
@ -374,7 +378,10 @@ function resetKeyMappingConfig() {
}"
>
<template #icon>
<NIcon><Settings /></NIcon>
<NIcon>
<ReturnUpBack v-if="keyboardStore.editSwipePointsFlag" />
<Settings v-else />
</NIcon>
</template>
</NButton>
<div

View File

@ -0,0 +1,354 @@
<script setup lang="ts">
import { computed, ref } from "vue";
import { useGlobalStore } from "../../store/global";
import {
NIcon,
NButton,
NFormItem,
NInput,
NH4,
NInputNumber,
useMessage,
} from "naive-ui";
import { Analytics, CloseCircle, Settings } from "@vicons/ionicons5";
import { useKeyboardStore } from "../../store/keyboard";
import { KeySwipe } from "../../keyMappingConfig";
import { useI18n } from "vue-i18n";
const props = defineProps<{
index: number;
}>();
const keyboardStore = useKeyboardStore();
const message = useMessage();
const store = useGlobalStore();
const { t } = useI18n();
const elementRef = ref<HTMLElement | null>(null);
const isActive = computed(
() => props.index === keyboardStore.activeButtonIndex
);
const keyMapping = computed(
() => store.editKeyMappingList[props.index] as KeySwipe
);
const trackPoints = computed(() => {
let s = "";
if (isActive.value) {
for (const point of keyMapping.value.pos) {
s += `${point.x},${point.y} `;
}
}
return s;
});
function dragHandler(downEvent: MouseEvent) {
keyboardStore.activeButtonIndex = props.index;
keyboardStore.showButtonSettingFlag = false;
const oldX = keyMapping.value.posX;
const oldY = keyMapping.value.posY;
const element = elementRef.value;
if (element) {
const keyboardElement = document.getElementById(
"keyboardElement"
) as HTMLElement;
const maxX = keyboardElement.clientWidth - 30;
const maxY = keyboardElement.clientHeight - 30;
const x = downEvent.clientX;
const y = downEvent.clientY;
const moveHandler = (moveEvent: MouseEvent) => {
let newX = oldX + moveEvent.clientX - x;
let newY = oldY + moveEvent.clientY - y;
newX = Math.max(30, Math.min(newX, maxX));
newY = Math.max(30, Math.min(newY, maxY));
keyMapping.value.posX = newX;
keyMapping.value.posY = newY;
};
window.addEventListener("mousemove", moveHandler);
const upHandler = () => {
window.removeEventListener("mousemove", moveHandler);
window.removeEventListener("mouseup", upHandler);
if (oldX !== keyMapping.value.posX || oldY !== keyMapping.value.posY) {
keyboardStore.edited = true;
}
};
window.addEventListener("mouseup", upHandler);
}
}
function delCurKeyMapping() {
keyboardStore.edited = true;
keyboardStore.activeButtonIndex = -1;
store.editKeyMappingList.splice(props.index, 1);
}
const settingPosX = ref(0);
const settingPosY = ref(0);
function showSetting() {
const keyboardElement = document.getElementById(
"keyboardElement"
) as HTMLElement;
const maxWidth = keyboardElement.clientWidth - 150;
const maxHeight = keyboardElement.clientHeight - 380;
settingPosX.value = Math.min(keyMapping.value.posX + 40, maxWidth);
settingPosY.value = Math.min(keyMapping.value.posY - 40, maxHeight);
keyboardStore.showButtonSettingFlag = true;
}
function editSwipePoints() {
message.info(t("pages.KeyBoard.Swipe.editTips"));
keyboardStore.showButtonSettingFlag = false;
keyboardStore.editSwipePointsFlag = true;
}
function swipePointDragHandlue(downEvent: MouseEvent, index: number) {
if (downEvent.button === 2) {
// del point
keyMapping.value.pos.splice(index, 1);
return;
}
if (downEvent.button !== 0) return;
const oldX = keyMapping.value.pos[index].x;
const oldY = keyMapping.value.pos[index].y;
const keyboardElement = document.getElementById(
"keyboardElement"
) as HTMLElement;
const maxX = keyboardElement.clientWidth;
const maxY = keyboardElement.clientHeight;
const x = downEvent.clientX;
const y = downEvent.clientY;
const moveHandler = (moveEvent: MouseEvent) => {
let newX = oldX + moveEvent.clientX - x;
let newY = oldY + moveEvent.clientY - y;
newX = Math.max(0, Math.min(newX, maxX));
newY = Math.max(0, Math.min(newY, maxY));
keyMapping.value.pos[index].x = newX;
keyMapping.value.pos[index].y = newY;
};
const upHandler = () => {
window.removeEventListener("mousemove", moveHandler);
window.removeEventListener("mouseup", upHandler);
};
window.addEventListener("mousemove", moveHandler);
window.addEventListener("mouseup", upHandler);
}
function swipeTrackClickHandler(event: MouseEvent) {
if (event.button !== 0) return;
console.log(event.target, event.currentTarget);
if (event.target !== event.currentTarget) return;
keyMapping.value.pos.push({ x: event.clientX - 70, y: event.clientY - 30 });
}
</script>
<template>
<div
:class="{ active: isActive }"
:style="{
left: `${keyMapping.posX - 30}px`,
top: `${keyMapping.posY - 30}px`,
}"
@mousedown="dragHandler"
class="key-swipe"
ref="elementRef"
>
<NIcon size="30"><Analytics /></NIcon>
<span>{{ keyMapping.key }}</span>
<NButton
class="key-close-btn"
text
@click="delCurKeyMapping"
:type="isActive ? 'primary' : 'info'"
>
<template #icon>
<NIcon size="15">
<CloseCircle />
</NIcon>
</template>
</NButton>
<NButton
class="key-setting-btn"
text
@click="showSetting"
:type="isActive ? 'primary' : 'info'"
>
<template #icon>
<NIcon size="15">
<Settings />
</NIcon>
</template>
</NButton>
</div>
<div
class="key-setting"
v-if="isActive && keyboardStore.showButtonSettingFlag"
:style="{
left: `${settingPosX}px`,
top: `${settingPosY}px`,
}"
>
<NH4 prefix="bar">{{ $t("pages.KeyBoard.Swipe.swipe") }}</NH4>
<NFormItem :label="$t('pages.KeyBoard.Swipe.pos')">
<NButton type="success" @click="editSwipePoints">{{
$t("pages.KeyBoard.Swipe.editPos")
}}</NButton>
</NFormItem>
<NFormItem :label="$t('pages.KeyBoard.Swipe.interval')">
<NInputNumber
v-model:value="keyMapping.intervalBetweenPos"
:placeholder="$t('pages.KeyBoard.Swipe.intervalPlaceholder')"
@update:value="keyboardStore.edited = true"
/>
</NFormItem>
<NFormItem :label="$t('pages.KeyBoard.setting.pointerID')">
<NInputNumber
v-model:value="keyMapping.pointerId"
:min="0"
:placeholder="$t('pages.KeyBoard.setting.pointerIDPlaceholder')"
@update:value="keyboardStore.edited = true"
/>
</NFormItem>
<NFormItem :label="$t('pages.KeyBoard.setting.note')">
<NInput
v-model:value="keyMapping.note"
:placeholder="$t('pages.KeyBoard.setting.notePlaceholder')"
@update:value="keyboardStore.edited = true"
/>
</NFormItem>
</div>
<template v-if="isActive">
<div
v-if="isActive"
class="track"
:class="{ 'edit-track': keyboardStore.editSwipePointsFlag }"
>
<svg @click="swipeTrackClickHandler">
<polyline :points="trackPoints" />
<circle
v-for="(pos, i) in keyMapping.pos"
:cx="pos.x"
:cy="pos.y"
r="5"
@mousedown="(e) => swipePointDragHandlue(e, i)"
/>
<text v-for="(pos, i) in keyMapping.pos" :x="pos.x + 5" :y="pos.y - 5">
{{ i }}
</text>
</svg>
</div>
</template>
</template>
<style scoped lang="scss">
.track {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
z-index: -1;
svg {
height: 100%;
width: 100%;
polyline {
fill: none;
stroke: var(--primary-hover-color);
stroke-width: 2;
}
circle {
cursor: pointer;
fill: var(--primary-color);
&:hover {
fill: var(--primary-pressed-color);
}
}
text {
cursor: default;
fill: var(--primary-pressed-color);
font-size: 15px;
text-anchor: end-alignment;
}
}
}
.edit-track {
z-index: 4;
background-color: rgba(0, 0, 0, 0.6);
}
.key-setting {
position: absolute;
display: flex;
flex-direction: column;
padding: 10px 20px;
box-sizing: border-box;
width: 150px;
height: 380px;
border-radius: 5px;
border: 2px solid var(--light-color);
background-color: var(--bg-color);
z-index: 3;
}
.key-swipe {
position: absolute;
height: 60px;
width: 60px;
box-sizing: border-box;
border-radius: 50%;
border: 2px solid var(--blue-color);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
font-size: 10px;
font-weight: bold;
cursor: pointer;
.n-icon {
color: var(--blue-color);
}
&:not(.active):hover {
border: 2px solid var(--light-color);
color: var(--light-color);
.n-icon {
color: var(--light-color);
}
}
.key-close-btn {
position: absolute;
left: 65px;
bottom: 45px;
}
.key-setting-btn {
position: absolute;
left: 65px;
top: 45px;
}
}
.active {
border: 2px solid var(--primary-color);
color: var(--primary-color);
z-index: 2;
.n-icon {
color: var(--primary-color);
}
}
</style>

View File

@ -151,7 +151,8 @@
"Sight": "Front sight",
"Fire": "Fire",
"existFire": "Fire button already exists",
"existSight": "Front sight button already exists"
"existSight": "Front sight button already exists",
"Swipe": "Swipe"
},
"buttonKeyRepeat": "Key repeat: {0}",
"KeyCommon": {
@ -253,6 +254,14 @@
"scaleX": "Horizontal sensitivity",
"scalePlaceholder": "Please enter sensitivity",
"scaleY": "Vertical sensitivity"
},
"Swipe": {
"swipe": "Swipe",
"interval": "Swipe time interval",
"intervalPlaceholder": "Enter the time interval between points",
"pos": "Points",
"editPos": "Edit",
"editTips": "Left-click on a blank area to add a new coordinate point. \nLeft-click and drag to move a specific point, and right-click to delete the point."
}
}
},

View File

@ -144,7 +144,8 @@
"Sight": "准星",
"Fire": "开火",
"existSight": "已存在准星按钮",
"existFire": "已存在开火按钮"
"existFire": "已存在开火按钮",
"Swipe": "滑动"
},
"buttonKeyRepeat": "按键重复: {0}",
"noSaveDialog": {
@ -253,6 +254,14 @@
"scaleX": "水平灵敏度",
"scaleY": "垂直灵敏度",
"scalePlaceholder": "请输入灵敏度"
},
"Swipe": {
"swipe": "滑动",
"interval": "滑动时间间隔",
"intervalPlaceholder": "输入坐标点之间的时间间隔",
"pos": "坐标点",
"editPos": "编辑",
"editTips": "左键点击空白区域添加新坐标点。左键拖拽移动特定坐标点,右键删除特定坐标点"
}
}
},

View File

@ -6,6 +6,7 @@ export const useKeyboardStore = defineStore("keyboard", () => {
const showSettingFlag = ref(false);
const showButtonSettingFlag = ref(false);
const showButtonAddFlag = ref(false);
const editSwipePointsFlag = ref(false);
const activeButtonIndex = ref(-1);
const activeSteeringWheelButtonKeyIndex = ref(-1);
const edited = ref(false);
@ -15,6 +16,7 @@ export const useKeyboardStore = defineStore("keyboard", () => {
showSettingFlag,
showButtonSettingFlag,
showButtonAddFlag,
editSwipePointsFlag,
activeButtonIndex,
activeSteeringWheelButtonKeyIndex,
edited,