@@ -11,3 +11,4 @@ node_modules | |||||
__pycache__ | __pycache__ | ||||
.vscode | .vscode | ||||
*.mjs | *.mjs | ||||
build |
@@ -1,6 +1,6 @@ | |||||
Settings: | Settings: | ||||
Advanced: advanced settings | |||||
Personalization: personalization | |||||
Advanced: Advanced Settings | |||||
Personalization: Personalization | |||||
button: | button: | ||||
about: About | about: About | ||||
back: Back | back: Back | ||||
@@ -21,7 +21,7 @@ | |||||
"pre:windows": "pyinstaller --clean .\\app\\spec\\windows-pre.spec", | "pre:windows": "pyinstaller --clean .\\app\\spec\\windows-pre.spec", | ||||
"pre:folder": "shx rm -rf build && vite build && pyinstaller --clean .\\app\\spec\\windows-folder-pre.spec", | "pre:folder": "shx rm -rf build && vite build && pyinstaller --clean .\\app\\spec\\windows-folder-pre.spec", | ||||
"build": "shx rm -rf build && vite build && run-script-os", | "build": "shx rm -rf build && vite build && run-script-os", | ||||
"build:windows": "pyinstaller -w --clean .\\app\\spec\\windows.spec", | |||||
"build:windows": "pyinstaller --clean .\\app\\spec\\windows.spec", | |||||
"build:folder": "shx rm -rf build && vite build && pyinstaller --clean .\\app\\spec\\windows-folder.spec" | "build:folder": "shx rm -rf build && vite build && pyinstaller --clean .\\app\\spec\\windows-folder.spec" | ||||
}, | }, | ||||
"dependencies": { | "dependencies": { | ||||
@@ -98,7 +98,6 @@ declare global { | |||||
const toReactive: typeof import('@vueuse/core')['toReactive'] | const toReactive: typeof import('@vueuse/core')['toReactive'] | ||||
const toRef: typeof import('vue')['toRef'] | const toRef: typeof import('vue')['toRef'] | ||||
const toRefs: typeof import('vue')['toRefs'] | const toRefs: typeof import('vue')['toRefs'] | ||||
const toggleDark: typeof import('./composables/dark')['toggleDark'] | |||||
const triggerRef: typeof import('vue')['triggerRef'] | const triggerRef: typeof import('vue')['triggerRef'] | ||||
const tryOnBeforeMount: typeof import('@vueuse/core')['tryOnBeforeMount'] | const tryOnBeforeMount: typeof import('@vueuse/core')['tryOnBeforeMount'] | ||||
const tryOnBeforeUnmount: typeof import('@vueuse/core')['tryOnBeforeUnmount'] | const tryOnBeforeUnmount: typeof import('@vueuse/core')['tryOnBeforeUnmount'] | ||||
@@ -378,7 +377,6 @@ declare module 'vue' { | |||||
readonly toReactive: UnwrapRef<typeof import('@vueuse/core')['toReactive']> | readonly toReactive: UnwrapRef<typeof import('@vueuse/core')['toReactive']> | ||||
readonly toRef: UnwrapRef<typeof import('vue')['toRef']> | readonly toRef: UnwrapRef<typeof import('vue')['toRef']> | ||||
readonly toRefs: UnwrapRef<typeof import('vue')['toRefs']> | readonly toRefs: UnwrapRef<typeof import('vue')['toRefs']> | ||||
readonly toggleDark: UnwrapRef<typeof import('./composables/dark')['toggleDark']> | |||||
readonly triggerRef: UnwrapRef<typeof import('vue')['triggerRef']> | readonly triggerRef: UnwrapRef<typeof import('vue')['triggerRef']> | ||||
readonly tryOnBeforeMount: UnwrapRef<typeof import('@vueuse/core')['tryOnBeforeMount']> | readonly tryOnBeforeMount: UnwrapRef<typeof import('@vueuse/core')['tryOnBeforeMount']> | ||||
readonly tryOnBeforeUnmount: UnwrapRef<typeof import('@vueuse/core')['tryOnBeforeUnmount']> | readonly tryOnBeforeUnmount: UnwrapRef<typeof import('@vueuse/core')['tryOnBeforeUnmount']> | ||||
@@ -15,5 +15,6 @@ declare module '@vue/runtime-core' { | |||||
README: typeof import('./components/README.md')['default'] | README: typeof import('./components/README.md')['default'] | ||||
RouterLink: typeof import('vue-router')['RouterLink'] | RouterLink: typeof import('vue-router')['RouterLink'] | ||||
RouterView: typeof import('vue-router')['RouterView'] | RouterView: typeof import('vue-router')['RouterView'] | ||||
Setting: typeof import('./components/Setting.vue')['default'] | |||||
} | } | ||||
} | } |
@@ -0,0 +1,213 @@ | |||||
<script setup> | |||||
defineProps({ | |||||
settingData: { | |||||
type: Array, | |||||
default: () => [], | |||||
}, | |||||
settingName: { | |||||
type: String, | |||||
default: '', | |||||
}, | |||||
}) | |||||
const { t } = useI18n() | |||||
</script> | |||||
<template> | |||||
<div> | |||||
<div class="setting-title text-left text-2xl ml-10"> | |||||
{{ t($props.settingName) }}: | |||||
</div> | |||||
<div class="setting-items my-3 py-2 border mx-5 rounded-md"> | |||||
<div v-for="item in $props.settingData" :key="item" class="setting-item my-1"> | |||||
<div v-if="Array.isArray(item.status)" class="flex justify-between mx-8"> | |||||
<div class="setting-item-title self-center flex justify-center items-center" :data-tip="item.description" :class="!!item.description ? 'tooltip tooltip-primary tooltip-right' : ''"> | |||||
{{ t(item.name) }}<div v-if="!!item.description" i-carbon-information class="ml-1 " /> | |||||
</div> | |||||
<select class="select select-sm max-w-xs"> | |||||
<option v-for="item_ in item.status" :key="item_" :selected="item_.status"> | |||||
{{ item_.name }} | |||||
</option> | |||||
</select> | |||||
</div> | |||||
<div v-else-if="typeof (item.status) == 'number'" class="flex justify-between mx-8 items-center"> | |||||
<div class="setting-item-title self-center flex justify-center items-center " :data-tip="item.description" :class="!!item.description ? 'tooltip tooltip-primary tooltip-right' : ''"> | |||||
{{ t(item.name) }}<div v-if="!!item.description" i-carbon-information class="ml-1 " /> | |||||
</div> | |||||
<input type="range" min="0" max="100" :value="item.status * 100" class="range range-xs" step="5"> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</template> | |||||
<style scoped> | |||||
.input-group > *, | |||||
.input-group > .input, | |||||
.input-group > .select { | |||||
border-radius: 0px; | |||||
} | |||||
.select { | |||||
display: inline-flex; | |||||
flex-shrink: 0; | |||||
cursor: pointer; | |||||
user-select: none; | |||||
appearance: none; | |||||
height: 3rem/* 48px */; | |||||
padding-left: 1rem/* 16px */; | |||||
padding-right: 2.5rem/* 40px */; | |||||
padding-right: 2.5rem/* 40px */; | |||||
font-size: 0.875rem/* 14px */; | |||||
line-height: 1.25rem/* 20px */; | |||||
line-height: 2; | |||||
min-height: 3rem/* 48px */; | |||||
border-width: 1px; | |||||
border-color: hsl(var(--bc) / var(--tw-border-opacity)); | |||||
--tw-border-opacity: 0; | |||||
--tw-bg-opacity: 1; | |||||
background-color: hsl(var(--b1) / var(--tw-bg-opacity)); | |||||
font-weight: 600; | |||||
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; | |||||
transition-duration: 200ms; | |||||
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); | |||||
border-radius: var(--rounded-btn, 0.5rem); | |||||
background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%); | |||||
background-position: calc(100% - 20px) calc(1px + 50%), calc(100% - 16px) calc(1px + 50%); | |||||
background-size: 4px 4px, 4px 4px; | |||||
background-repeat: no-repeat; | |||||
} | |||||
.select[multiple] { | |||||
height: auto; | |||||
} | |||||
.select:focus { | |||||
outline: 0px solid hsla(var(--bc) / 0.2); | |||||
outline-offset: 2px; | |||||
} | |||||
.select-disabled, | |||||
.select[disabled] { | |||||
cursor: not-allowed; | |||||
--tw-border-opacity: 1; | |||||
border-color: hsl(var(--b2, var(--b1)) / var(--tw-border-opacity)); | |||||
--tw-bg-opacity: 1; | |||||
background-color: hsl(var(--b2, var(--b1)) / var(--tw-bg-opacity)); | |||||
--tw-text-opacity: 0.2; | |||||
} | |||||
.select-disabled::placeholder, | |||||
.select[disabled]::placeholder { | |||||
color: hsl(var(--bc) / var(--tw-placeholder-opacity)); | |||||
--tw-placeholder-opacity: 0.2; | |||||
} | |||||
.select-multiple, | |||||
.select[multiple], | |||||
.select[size].select:not([size="1"]) { | |||||
background-image: none; | |||||
padding-right: 1rem/* 16px */; | |||||
} | |||||
.select-multiple, | |||||
.select[multiple], | |||||
.select[size].select:not([size="1"]) { | |||||
background-image: none; | |||||
padding-right: 1rem/* 16px */; | |||||
} | |||||
.select-multiple, | |||||
.select[multiple], | |||||
.select[size].select:not([size="1"]) { | |||||
background-image: none; | |||||
padding-right: 1rem/* 16px */; | |||||
} | |||||
.select-sm { | |||||
height: 2rem/* 32px */; | |||||
padding-left: 0.75rem/* 12px */; | |||||
padding-right: 2rem/* 32px */; | |||||
font-size: 0.875rem/* 14px */; | |||||
line-height: 2rem/* 32px */; | |||||
min-height: 2rem/* 32px */; | |||||
} | |||||
[dir="rtl"] .select-sm { | |||||
padding-right: 0.75rem/* 12px */; | |||||
padding-left: 2rem/* 32px */; | |||||
} | |||||
.range { | |||||
height: 1.5rem/* 24px */; | |||||
width: 8rem; | |||||
cursor: pointer; | |||||
appearance: none; | |||||
-webkit-appearance: none; | |||||
--range-shdw: var(--bc); | |||||
overflow: hidden; | |||||
background-color: transparent; | |||||
border-radius: var(--rounded-box, 1rem); | |||||
} | |||||
.range:focus { | |||||
outline: none; | |||||
} | |||||
.range:focus-visible::-webkit-slider-thumb { | |||||
--focus-shadow: 0 0 0 6px hsl(var(--b1)) inset, 0 0 0 2rem hsl(var(--range-shdw)) inset; | |||||
} | |||||
.range:focus-visible::-moz-range-thumb { | |||||
--focus-shadow: 0 0 0 6px hsl(var(--b1)) inset, 0 0 0 2rem hsl(var(--range-shdw)) inset; | |||||
} | |||||
.range::-webkit-slider-runnable-track { | |||||
height: 0.5rem/* 8px */; | |||||
width: 100%; | |||||
border-radius: var(--rounded-box, 1rem); | |||||
background-color: hsla(var(--bc) / 0.1); | |||||
} | |||||
.range::-moz-range-track { | |||||
height: 0.5rem/* 8px */; | |||||
width: 100%; | |||||
border-radius: var(--rounded-box, 1rem); | |||||
background-color: hsla(var(--bc) / 0.1); | |||||
} | |||||
.range::-webkit-slider-thumb { | |||||
background-color: hsl(var(--b1)); | |||||
position: relative; | |||||
height: 1.5rem/* 24px */; | |||||
width: 1.5rem/* 24px */; | |||||
border-style: none; | |||||
border-radius: var(--rounded-box, 1rem); | |||||
appearance: none; | |||||
-webkit-appearance: none; | |||||
top: 50%; | |||||
color: hsl(var(--range-shdw)); | |||||
transform: translateY(-50%); | |||||
--filler-size: 100rem/* 1600px */; | |||||
--filler-offset: 0.6rem/* 9.6px */; | |||||
box-shadow: 0 0 0 3px hsl(var(--range-shdw)) inset, var(--focus-shadow, 0 0), calc(var(--filler-size) * -1 - var(--filler-offset)) 0 0 var(--filler-size); | |||||
} | |||||
.range::-moz-range-thumb { | |||||
background-color: hsl(var(--b1)); | |||||
position: relative; | |||||
height: 1.5rem/* 24px */; | |||||
width: 1.5rem/* 24px */; | |||||
border-style: none; | |||||
border-radius: var(--rounded-box, 1rem); | |||||
top: 50%; | |||||
color: hsl(var(--range-shdw)); | |||||
--filler-size: 100rem/* 1600px */; | |||||
--filler-offset: 0.5rem/* 8px */; | |||||
box-shadow: 0 0 0 3px hsl(var(--range-shdw)) inset, var(--focus-shadow, 0 0), calc(var(--filler-size) * -1 - var(--filler-offset)) 0 0 var(--filler-size); | |||||
} | |||||
.range-xs { | |||||
height: .5rem/* 16px */; | |||||
} | |||||
.range-xs::-webkit-slider-runnable-track { | |||||
height: 0.125rem/* 4px */; | |||||
} | |||||
.range-xs::-moz-range-track { | |||||
height: 0.125rem/* 4px */; | |||||
} | |||||
.range-xs::-webkit-slider-thumb { | |||||
height: .5rem/* 16px */; | |||||
width: .5rem/* 16px */; | |||||
--filler-offset: 0.2rem/* 6.4px */; | |||||
} | |||||
.range-xs::-moz-range-thumb { | |||||
height: .5rem/* 16px */; | |||||
width: .5rem/* 16px */; | |||||
--filler-offset: 0.2rem/* 6.4px */; | |||||
} | |||||
</style> |
@@ -4,14 +4,19 @@ defineProps({ | |||||
type: String, | type: String, | ||||
default: '', | default: '', | ||||
}, | }, | ||||
disabled: | |||||
{ | |||||
type: Boolean, | |||||
default: false, | |||||
}, | |||||
}) | }) | ||||
</script> | </script> | ||||
<template> | <template> | ||||
<div> | <div> | ||||
<label class="flex items-center cursor-pointer justify-center pt-4"> | |||||
<label class="flex items-center cursor-pointer justify-center "> | |||||
<span class="label-text pr-2 text-lg">{{ text }}</span> | <span class="label-text pr-2 text-lg">{{ text }}</span> | ||||
<input type="checkbox" class="toggle" checked> | |||||
<input type="checkbox" class="toggle" checked :disabled="$props.disabled"> | |||||
</label> | </label> | ||||
</div> | </div> | ||||
</template> | </template> | ||||
@@ -11,7 +11,7 @@ router.currentRoute.value.path === '/index.html' && router.push('/') // redirect | |||||
</div> | </div> | ||||
<RouterView /> | <RouterView /> | ||||
<div> | <div> | ||||
<button btn text-sm m="3 t8" @click="router.back"> | |||||
<button class="btn" text-sm m="3 t8" @click="router.back"> | |||||
{{ t('button.back') }} | {{ t('button.back') }} | ||||
</button> | </button> | ||||
</div> | </div> | ||||
@@ -2,8 +2,8 @@ | |||||
<main class="px-4 py-10 text-center text-gray-700 dark:text-gray-200"> | <main class="px-4 py-10 text-center text-gray-700 dark:text-gray-200"> | ||||
<RouterView /> | <RouterView /> | ||||
<Footer /> | <Footer /> | ||||
<div class="mt-5 mx-auto text-center opacity-75 dark:opacity-50 text-sm"> | |||||
<!-- <div class="mt-5 mx-auto text-center opacity-75 dark:opacity-50 text-sm"> | |||||
[Default Layout] | [Default Layout] | ||||
</div> | |||||
</div> --> | |||||
</main> | </main> | ||||
</template> | </template> |
@@ -0,0 +1,122 @@ | |||||
<script setup> | |||||
const { t } = useI18n() | |||||
const ControlSetting = [ | |||||
{ | |||||
name: '控制设置', | |||||
status: [{ | |||||
name: '开/关/开', | |||||
status: true, | |||||
}, { | |||||
name: '关/开/关', | |||||
status: false, | |||||
}], | |||||
description: '控制设置', | |||||
}, | |||||
{ | |||||
name: '控制功能', | |||||
status: [{ | |||||
name: '悬停鼠标', | |||||
status: true, | |||||
}, { | |||||
name: '单击按钮', | |||||
status: false, | |||||
}], | |||||
}, | |||||
] | |||||
const ModelSetting = [ | |||||
{ | |||||
name: '模型版本设置', | |||||
status: [{ | |||||
name: '1.0.0', | |||||
status: true, | |||||
}], | |||||
description: '目前仅有官方提供模型,可通过个性化设置进行修改', | |||||
link: '/Personalization', | |||||
}, | |||||
{ | |||||
name: '置信度', | |||||
status: 0.5, | |||||
}, | |||||
{ | |||||
name: 'confThreshold', | |||||
status: 0.5, | |||||
}, | |||||
{ | |||||
name: 'nmsThreshold', | |||||
status: 0.6, | |||||
}, | |||||
{ | |||||
name: '图片载入方式', | |||||
status: [{ | |||||
name: '不裁剪', | |||||
status: true, | |||||
}, { | |||||
name: '居中裁剪成224*224', | |||||
status: false, | |||||
}, | |||||
{ | |||||
name: '居中裁剪成320*320', | |||||
status: false, | |||||
}], | |||||
}, | |||||
] | |||||
const otherSetting = [ | |||||
{ | |||||
name: '系统摄像头选择', | |||||
status: [{ | |||||
name: '摄像头0', | |||||
status: true, | |||||
}], | |||||
}, | |||||
] | |||||
</script> | |||||
<template> | |||||
<div> | |||||
<div class="hero"> | |||||
<div class="hero-content flex-col items-end lg:flex-row-reverse "> | |||||
<div class="text-3xl flex items-center"> | |||||
<router-link to="/"> | |||||
<div i-carbon-arrow-left class="mr-2 hover:bg-primary" /> | |||||
</router-link> | |||||
{{ t('Settings.Advanced') }} | |||||
</div> | |||||
<div class="text-gray-500"> | |||||
修改后重启生效 | |||||
</div> | |||||
</div> | |||||
</div> | |||||
<div class="mt-4 mx-3"> | |||||
<setting setting-name="控制" :setting-data="ControlSetting" class="" /> | |||||
<setting setting-name="模型" :setting-data="ModelSetting" class="mt-4" /> | |||||
<setting setting-name="其他" :setting-data="otherSetting" class="mt-4" /> | |||||
</div> | |||||
</div> | |||||
</template> | |||||
<style scoped> | |||||
.hero { | |||||
display: grid; | |||||
width: 100%; | |||||
place-items: center; | |||||
background-size: cover; | |||||
background-position: center; | |||||
justify-content: start; | |||||
} | |||||
.hero > * { | |||||
grid-column-start: 1; | |||||
grid-row-start: 1; | |||||
} | |||||
.hero-content { | |||||
z-index: 0; | |||||
display: flex; | |||||
align-items: left; | |||||
justify-content: center; | |||||
max-width: 80rem/* 1280px */; | |||||
gap: 1rem/* 16px */; | |||||
padding: 1rem/* 16px */; | |||||
} | |||||
</style> |
@@ -29,17 +29,22 @@ const { t } = useI18n() | |||||
</script> | </script> | ||||
<template> | <template> | ||||
<div class="flex justify-center"> | |||||
<div class="flex justify-center "> | |||||
<div class=""> | <div class=""> | ||||
<div class="pr-9"> | <div class="pr-9"> | ||||
<div class="text-5xl "> | |||||
<div class="text-5xl bg-clip-text text-transparent bg-gradient-to-r from-cyan-500 to-sky-800 font-extrabold"> | |||||
EMC | EMC | ||||
</div> | </div> | ||||
<div class="text-gray-400"> | <div class="text-gray-400"> | ||||
眼控/嘴控小工具 | 眼控/嘴控小工具 | ||||
</div> | </div> | ||||
<d-toggle text="启用" /> | |||||
<d-toggle text="触发提醒" /> | |||||
<div class="bg-gray-100 p-3 rounded-md mt-4"> | |||||
<div>实时情况:</div> | |||||
<d-toggle text="闭眼" class="pt-2" :disabled="true" /> | |||||
<d-toggle text="张嘴" class="pt-2" :disabled="true" /> | |||||
</div> | |||||
<d-toggle text="启用" class="pt-4" /> | |||||
<d-toggle text="触发提醒" class="pt-4" /> | |||||
<d-select class="mt-5" /> | <d-select class="mt-5" /> | ||||
</div> | </div> | ||||
<div class="item-center flex flex-col pr-9 mt-5"> | <div class="item-center flex flex-col pr-9 mt-5"> | ||||