mirror of
https://github.com/PhotonVision/photonvision
synced 2026-06-29 02:21:41 +00:00
cleanup UI for 3.0
This commit is contained in:
2947
chameleon-client/package-lock.json
generated
2947
chameleon-client/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -8,27 +8,28 @@
|
||||
"lint": "vue-cli-service lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^0.19.0",
|
||||
"axios": "^0.19.2",
|
||||
"core-js": "^2.6.11",
|
||||
"downloadjs": "^1.4.7",
|
||||
"material-design-icons-iconfont": "^5.0.1",
|
||||
"msgpack5": "^4.2.1",
|
||||
"vue": "^2.6.11",
|
||||
"vue-axios": "^2.1.5",
|
||||
"vue-native-websocket": "^2.0.13",
|
||||
"vue-router": "^3.0.3",
|
||||
"vuetify": "^2.2.1",
|
||||
"vuex": "^3.1.2"
|
||||
"vue-native-websocket": "^2.0.14",
|
||||
"vue-router": "^3.1.6",
|
||||
"vuetify": "^2.2.17",
|
||||
"vuex": "^3.1.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@mdi/font": "^4.7.95",
|
||||
"@mdi/font": "^4.9.95",
|
||||
"@vue/cli-plugin-babel": "^3.12.1",
|
||||
"@vue/cli-plugin-eslint": "^3.12.1",
|
||||
"@vue/cli-service": "^3.12.1",
|
||||
"babel-eslint": "^10.0.1",
|
||||
"@vue/cli-plugin-eslint": "^4.2.3",
|
||||
"@vue/cli-service": "^4.2.3",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"eslint": "^5.16.0",
|
||||
"eslint-plugin-vue": "^5.0.0",
|
||||
"papaparse": "^5.1.1",
|
||||
"sass": "^1.24.2",
|
||||
"sass": "^1.26.3",
|
||||
"sass-loader": "^7.1.0",
|
||||
"vue-cli-plugin-vuetify": "^0.6.3",
|
||||
"vue-template-compiler": "^2.6.11",
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<v-toolbar-title id="title">Chameleon Vision</v-toolbar-title>
|
||||
<div class="flex-grow-1"></div>
|
||||
<v-toolbar-items>
|
||||
<v-tabs dark height="48" slider-color="#4baf62">
|
||||
<v-tabs background-color="#272727" dark height="48" slider-color="#4baf62">
|
||||
<v-tab to="vision">Vision</v-tab>
|
||||
<v-tab to="settings">Settings</v-tab>
|
||||
</v-tabs>
|
||||
@@ -31,7 +31,6 @@
|
||||
<script>
|
||||
export default {
|
||||
name: 'App',
|
||||
|
||||
components: {},
|
||||
methods: {
|
||||
handleMessage(key, value) {
|
||||
@@ -41,7 +40,6 @@
|
||||
this.$store.commit('setPipeValues', {[key]: value});
|
||||
} else {
|
||||
switch (key) {
|
||||
|
||||
default: {
|
||||
console.log(key + " : " + value);
|
||||
}
|
||||
@@ -66,9 +64,7 @@
|
||||
created() {
|
||||
this.$options.sockets.onmessage = (data) => {
|
||||
try {
|
||||
|
||||
let message = this.$msgPack.decode(data.data);
|
||||
|
||||
for (let prop in message) {
|
||||
if (message.hasOwnProperty(prop)) {
|
||||
this.handleMessage(prop, message[prop]);
|
||||
@@ -104,10 +100,6 @@
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
.tabClass {
|
||||
color: #4baf62;
|
||||
}
|
||||
|
||||
.container {
|
||||
background-color: #212121;
|
||||
padding: 0 !important;
|
||||
|
||||
@@ -131,7 +131,7 @@
|
||||
this.grad = this.ctx.createLinearGradient(400, 800, 400, 600);
|
||||
this.grad.addColorStop(0, "rgb(119,119,119)");
|
||||
this.grad.addColorStop(0.05, "rgba(14,92,22,0.96)");
|
||||
this.grad.addColorStop(0.8, "rgba(43,43,43,0.48)");
|
||||
this.grad.addColorStop(0.8, 'rgba(43,43,43,0.48)');
|
||||
|
||||
// setting canvas context values for drawing
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
if (isNaN(m) === false && isNaN(b) === false) {
|
||||
this.sendSlope(m, b, true);
|
||||
} else {
|
||||
this.$emit('snackbar',"Points are too close");
|
||||
this.$emit('snackbar', "Points are too close");
|
||||
}
|
||||
this.pointA = undefined;
|
||||
this.pointB = undefined;
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
this.handleInput('point', this.rawPoint);
|
||||
this.$emit('update');
|
||||
} else {
|
||||
this.$emit('snackbar',"No target found");
|
||||
this.$emit('snackbar', "No target found");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,9 +22,12 @@
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
hoverClass() {
|
||||
if (this.hover !== undefined) {
|
||||
return "hover";
|
||||
hoverClass: {
|
||||
get() {
|
||||
if (this.hover !== undefined) {
|
||||
return "hover";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
</v-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
s
|
||||
<script>
|
||||
export default {
|
||||
name: 'Input',
|
||||
@@ -21,7 +21,7 @@
|
||||
},
|
||||
methods: {
|
||||
handleKeyboard(event) {
|
||||
if (event.key == "Enter") {
|
||||
if (event.key === "Enter") {
|
||||
this.$emit("Enter");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,9 +10,9 @@ import VueAxios from "vue-axios";
|
||||
|
||||
Vue.config.productionTip = false;
|
||||
|
||||
if (process.env.NODE_ENV === "production"){
|
||||
if (process.env.NODE_ENV === "production") {
|
||||
Vue.prototype.$address = location.host;
|
||||
} else if (process.env.NODE_ENV === "development"){
|
||||
} else if (process.env.NODE_ENV === "development") {
|
||||
Vue.prototype.$address = location.hostname + ":5800";
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ const url = 'ws://' + Vue.prototype.$address + '/websocket';
|
||||
var ws = new WebSocket(url);
|
||||
ws.binaryType = "arraybuffer";
|
||||
|
||||
Vue.use(VueNativeSock, url,{
|
||||
Vue.use(VueNativeSock, url, {
|
||||
WebSocket: ws
|
||||
});
|
||||
Vue.use(VueAxios, axios);
|
||||
|
||||
@@ -28,7 +28,7 @@ function colorPickerClick(event, currentFunction, currentRange) {
|
||||
|
||||
function eyeDrop(pixel) {
|
||||
let hsv = RGBtoHSV(pixel);
|
||||
let range = widenRange([hsv,hsv.slice(0)]);//sends hsv and a copy of hsv
|
||||
let range = widenRange([hsv, hsv.slice(0)]);//sends hsv and a copy of hsv
|
||||
return range
|
||||
}
|
||||
|
||||
|
||||
@@ -1,27 +1,29 @@
|
||||
import Vue from 'vue'
|
||||
import Router from 'vue-router'
|
||||
|
||||
Vue.use(Router);
|
||||
|
||||
function lazyLoad(view){
|
||||
return() => import(`@/views/${view}.vue`)
|
||||
function lazyLoad(view) {
|
||||
return () => import(`@/views/${view}.vue`)
|
||||
}
|
||||
|
||||
export default new Router({
|
||||
// mode: 'history',
|
||||
base: process.env.BASE_URL,
|
||||
routes: [
|
||||
{
|
||||
path: '/',
|
||||
redirect:'/vision'
|
||||
},
|
||||
{
|
||||
path: '/vision',
|
||||
name: 'Vision',
|
||||
component: lazyLoad('Camera')
|
||||
},
|
||||
{
|
||||
path: '/settings',
|
||||
name: 'Settings',
|
||||
component: lazyLoad('Settings')
|
||||
},
|
||||
]
|
||||
// mode: 'history',
|
||||
base: process.env.BASE_URL,
|
||||
routes: [
|
||||
{
|
||||
path: '/',
|
||||
redirect: '/vision'
|
||||
},
|
||||
{
|
||||
path: '/vision',
|
||||
name: 'Vision',
|
||||
component: lazyLoad('Camera')
|
||||
},
|
||||
{
|
||||
path: '/settings',
|
||||
name: 'Settings',
|
||||
component: lazyLoad('Settings')
|
||||
},
|
||||
]
|
||||
})
|
||||
|
||||
@@ -39,8 +39,8 @@ export default new Vuex.Store({
|
||||
videoModeIndex: 0,
|
||||
streamDivisor: 0,
|
||||
is3D: false,
|
||||
targetRegion:0,
|
||||
targetOrientation:1
|
||||
targetRegion: 0,
|
||||
targetOrientation: 1
|
||||
},
|
||||
cameraSettings: {
|
||||
calibration: [],
|
||||
|
||||
@@ -123,9 +123,9 @@
|
||||
<tbody>
|
||||
<tr v-for="(value, index) in targets" :key="index">
|
||||
<td>{{ index}}</td>
|
||||
<td>{{ parseFloat(value.pitch).toFixed(2) }}</td>
|
||||
<td>{{ parseFloat(value.yaw).toFixed(2) }}</td>
|
||||
<td>{{ parseFloat(value.area).toFixed(2) }}</td>
|
||||
<td>{{ parseFloat(value.pitch).toFixed(2)}}</td>
|
||||
<td>{{ parseFloat(value.yaw).toFixed(2)}}</td>
|
||||
<td>{{ parseFloat(value.area).toFixed(2)}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</template>
|
||||
@@ -279,7 +279,7 @@
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
re: RegExp('^[A-Za-z0-9 \\-)(]*[A-Za-z0-9][A-Za-z0-9 \\-)(.]*$'),
|
||||
re: RegExp("^[A-Za-z0-9 \\-)(]*[A-Za-z0-9][A-Za-z0-9 \\-)(.]*$"),
|
||||
selectedTab: 0,
|
||||
// camera edit variables
|
||||
isCameraNameEdit: false,
|
||||
@@ -301,12 +301,13 @@
|
||||
},
|
||||
computed: {
|
||||
checkCameraName() {
|
||||
|
||||
if (this.newCameraName !== this.cameraList[this.currentCameraIndex]) {
|
||||
if (this.re.test(this.newCameraName)) {
|
||||
for (let cam in this.cameraList) {
|
||||
if (this.newCameraName === this.cameraList[cam]) {
|
||||
return "Camera by that name already Exists"
|
||||
if (this.cameraList.hasOwnProperty(cam)) {
|
||||
if (this.newCameraName === this.cameraList[cam]) {
|
||||
return "Camera by that name already Exists"
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -316,15 +317,15 @@
|
||||
return ""
|
||||
},
|
||||
checkPipelineName() {
|
||||
|
||||
if (this.newPipelineName !== this.pipelineList[this.currentPipelineIndex - 1] || this.isPipelineNameEdit === false) {
|
||||
if (this.re.test(this.newPipelineName)) {
|
||||
for (let pipe in this.pipelineList) {
|
||||
if (this.newPipelineName === this.pipelineList[pipe]) {
|
||||
return "A pipeline with this name already exists"
|
||||
if (this.pipelineList.hasOwnProperty(pipe)) {
|
||||
if (this.newPipelineName === this.pipelineList[pipe]) {
|
||||
return "A pipeline with this name already exists"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
return "Pipeline name can only contain letters, numbers, and spaces"
|
||||
}
|
||||
@@ -341,27 +342,11 @@
|
||||
},
|
||||
selectedComponent: {
|
||||
get() {
|
||||
if (this.currentPipelineIndex === 0) {
|
||||
return "InputTab"
|
||||
}
|
||||
switch (this.selectedTab) {
|
||||
case 0:
|
||||
return "InputTab";
|
||||
case 1:
|
||||
return "ThresholdTab";
|
||||
case 2:
|
||||
return "ContoursTab";
|
||||
case 3:
|
||||
return "OutputTab";
|
||||
case 4:
|
||||
return "pnpTab";
|
||||
}
|
||||
return "";
|
||||
return this.currentPipelineIndex === 0 ? "InputTab" : ["InputTab", "ThresholdTab", "ContoursTab", "OutputTab", "pnpTab"][this.selectedTab];
|
||||
}
|
||||
},
|
||||
targets: {
|
||||
get: function () {
|
||||
|
||||
return this.$store.state.point.targets;
|
||||
}
|
||||
},
|
||||
@@ -402,7 +387,7 @@
|
||||
}
|
||||
},
|
||||
streamAddress: {
|
||||
get: function () {
|
||||
get() {
|
||||
return "http://" + location.hostname + ":" + this.$store.state.port + "/stream.mjpg";
|
||||
}
|
||||
},
|
||||
@@ -421,12 +406,6 @@
|
||||
}
|
||||
|
||||
|
||||
.tableClass {
|
||||
padding-top: 5px;
|
||||
width: 70%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
th {
|
||||
width: 80px;
|
||||
text-align: center;
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
</v-btn>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<CVslider name="Contour simplification" v-model="value.accuracy" :min="0" :max="100" @input="handleData('accuracy')"/>
|
||||
<CVslider name="Contour simplification" v-model="value.accuracy" :min="0" :max="100"
|
||||
@input="handleData('accuracy')"/>
|
||||
<v-row>
|
||||
<v-col>
|
||||
<mini-map class="miniMapClass" :targets="targets" :horizontal-f-o-v="horizontalFOV"/>
|
||||
@@ -100,13 +101,13 @@
|
||||
this.uploadModel(this.selectedModel);
|
||||
},
|
||||
uploadModel(model) {
|
||||
this.axios.post("http://" + this.$address + "/api/vision/pnpModel", model).then((response) => {
|
||||
this.axios.post("http://" + this.$address + "/api/vision/pnpModel", model).then(() => {
|
||||
this.snackbar = {
|
||||
color: "success",
|
||||
text: "File uploaded successfully"
|
||||
};
|
||||
this.snack = true;
|
||||
}).catch((error) => {
|
||||
}).catch(() => {
|
||||
this.snackbar = {
|
||||
color: "error",
|
||||
text: "An error occurred"
|
||||
@@ -146,7 +147,9 @@
|
||||
mounted() {
|
||||
let tmp = [];
|
||||
for (let t in FRCtargetsConfig) {
|
||||
tmp.push({name: t, data: FRCtargetsConfig[t]})
|
||||
if (FRCtargetsConfig.hasOwnProperty(t)) {
|
||||
tmp.push({name: t, data: FRCtargetsConfig[t]})
|
||||
}
|
||||
}
|
||||
this.FRCtargets = tmp;
|
||||
}
|
||||
|
||||
@@ -41,10 +41,8 @@
|
||||
},
|
||||
computed: {
|
||||
isDisabled() {
|
||||
if (this.value.targetGroup === 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return this.value.targetGroup === 0;
|
||||
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
<CVselect name="Sort Mode" v-model="value.sortMode"
|
||||
:list="['Largest','Smallest','Highest','Lowest','Rightmost','Leftmost','Centermost']"
|
||||
@input="handleData('sortMode')"/>
|
||||
<CVselect v-model="value.targetRegion" name="Target Region" :list="['Center','Top','Bottom','Left','Right']" @input="handleData('targetRegion')"/>
|
||||
<CVselect v-model="value.targetRegion" name="Target Region" :list="['Center','Top','Bottom','Left','Right']"
|
||||
@input="handleData('targetRegion')"/>
|
||||
<CVselect name="Target Orientation" :list="['Portrait', 'Landscape']" v-model="value.targetOrientation"
|
||||
@input="handleData('targetOrientation')"/>
|
||||
<CVswitch name="Output multiple" v-model="value.multiple" @input="handleData('multiple')"/>
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
data() {
|
||||
return {
|
||||
selectedTab: 0,
|
||||
tabList:[General, Cameras]
|
||||
tabList: [General, Cameras]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
||||
@@ -30,12 +30,12 @@
|
||||
</v-col>
|
||||
<v-col>
|
||||
<v-btn small :color="cancellationModeButton.color" @click="sendCalibrationFinish"
|
||||
:disabled="checkCancelation">
|
||||
:disabled="checkCancellation">
|
||||
{{cancellationModeButton.text}}
|
||||
</v-btn>
|
||||
</v-col>
|
||||
<v-col>
|
||||
<v-btn color="whitesmoke" small @click="$refs.calibrationFile.click()">
|
||||
<v-btn color="whitesmoke" small @click="downloadBoard">
|
||||
Download Checkerboard
|
||||
</v-btn>
|
||||
<a ref="calibrationFile" style="color: black; text-decoration: none; display: none"
|
||||
@@ -106,6 +106,11 @@
|
||||
handleData(val) {
|
||||
this.handleInput(val, this.pipeline[val]);
|
||||
},
|
||||
downloadBoard() {
|
||||
this.axios.get("http://" + this.$address + require('../../assets/chessboard.png'), {responseType: 'blob'}).then((response) => {
|
||||
require('downloadjs')(response.data, "Calibration Board", "image/png")
|
||||
})
|
||||
},
|
||||
changeFps() {
|
||||
this.handleInput('videoModeIndex', this.filteredFpsList[this.pipeline['videoModeIndex']]['actualIndex']);
|
||||
},
|
||||
@@ -189,7 +194,7 @@
|
||||
checkResolution() {
|
||||
return this.resolutionIndex === undefined;
|
||||
},
|
||||
checkCancelation() {
|
||||
checkCancellation() {
|
||||
if (this.isCalibrating) {
|
||||
return false
|
||||
} else if (this.checkResolution) {
|
||||
@@ -218,10 +223,12 @@
|
||||
get() {
|
||||
let tmp_list = [];
|
||||
for (let i in this.$store.state.resolutionList) {
|
||||
let res = JSON.parse(JSON.stringify(this.$store.state.resolutionList[i]));
|
||||
if (!tmp_list.some(e => e.width === res.width && e.height === res.height)) {
|
||||
res['actualIndex'] = parseInt(i);
|
||||
tmp_list.push(res);
|
||||
if (this.$store.state.resolutionList.hasOwnProperty(i)) {
|
||||
let res = JSON.parse(JSON.stringify(this.$store.state.resolutionList[i]));
|
||||
if (!tmp_list.some(e => e.width === res.width && e.height === res.height)) {
|
||||
res['actualIndex'] = parseInt(i);
|
||||
tmp_list.push(res);
|
||||
}
|
||||
}
|
||||
}
|
||||
return tmp_list;
|
||||
@@ -231,11 +238,13 @@
|
||||
let selectedRes = this.$store.state.resolutionList[this.resolutionIndex];
|
||||
let tmpList = [];
|
||||
for (let i in this.$store.state.resolutionList) {
|
||||
let res = JSON.parse(JSON.stringify(this.$store.state.resolutionList[i]));
|
||||
if (!tmpList.some(e => e['fps'] === res['fps'])) {
|
||||
if (res.width === selectedRes.width && res.height === selectedRes.height) {
|
||||
res['actualIndex'] = parseInt(i);
|
||||
tmpList.push(res);
|
||||
if (this.$store.state.resolutionList.hasOwnProperty(i)) {
|
||||
let res = JSON.parse(JSON.stringify(this.$store.state.resolutionList[i]));
|
||||
if (!tmpList.some(e => e['fps'] === res['fps'])) {
|
||||
if (res.width === selectedRes.width && res.height === selectedRes.height) {
|
||||
res['actualIndex'] = parseInt(i);
|
||||
tmpList.push(res);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user