UI Redesign (#22)

* Rework UI into a new, responsive layout

* Send two streams (only one is currently downscaled)
This commit is contained in:
Declan Freeman-Gleason
2020-07-13 19:34:31 -07:00
committed by GitHub
parent aed92e7132
commit 8b46ad1cab
29 changed files with 945 additions and 559 deletions

View File

@@ -3,7 +3,6 @@
id="CameraStream"
:style="styleObject"
:src="address"
crossorigin="Anonymous"
alt=""
@click="e => $emit('click', e)"
>
@@ -13,19 +12,27 @@
export default {
name: "CvImage",
// eslint-disable-next-line vue/require-prop-types
props: ['address', 'scale'],
props: ['address', 'scale', 'maxHeight', 'maxHeightMd', 'maxHeightXl'],
data: () => {
return {}
},
computed: {
styleObject: {
get() {
return {
width: `${this.scale}%`,
height: `${this.scale}%`,
display: 'block',
margin: 'auto'
let ret = {
"object-fit": "contain",
"max-height": this.maxHeight,
width: `${this.scale}%`,
height: `${this.scale}%`,
};
if (this.$vuetify.breakpoint.xl) {
ret["max-height"] = this.maxHeightXl;
} else if (this.$vuetify.breakpoint.mdAndUp) {
ret["max-height"] = this.maxHeightMd;
}
return ret;
}
}

View File

@@ -4,10 +4,10 @@
dense
align="center"
>
<v-col :cols="3">
<span>{{ name }}</span>
<v-col cols="4">
<span class="ml-2">{{ name }}</span>
</v-col>
<v-col :cols="9">
<v-col cols="8">
<v-text-field
v-model="localValue"
dark

View File

@@ -1,6 +1,9 @@
<template>
<div>
<v-row dense align="center">
<v-row
dense
align="center"
>
<v-col :cols="2">
<span>{{ name }}</span>
</v-col>

View File

@@ -4,18 +4,18 @@
dense
align="center"
>
<v-col :cols="3">
<v-col :cols="12 - (selectCols || 9)">
<span>{{ name }}</span>
</v-col>
<v-col :cols="9">
<v-col :cols="selectCols || 9">
<v-select
v-model="localValue"
:items="indexList"
item-text="name"
item-value="index"
dark
color="#fcf6de"
item-color="blue"
color="accent"
item-color="secondary"
:disabled="disabled"
@change="$emit('rollback', localValue)"
/>
@@ -28,7 +28,7 @@
export default {
name: 'Select',
// eslint-disable-next-line vue/require-prop-types
props: ['list', 'name', 'value', 'disabled'],
props: ['list', 'name', 'value', 'disabled', 'selectCols'],
data() {
return {}
},

View File

@@ -1,10 +1,13 @@
<template>
<div>
<v-row dense align="center">
<v-col :cols="2">
<v-row
dense
align="center"
>
<v-col :cols="12 - (sliderCols || 8)">
<span>{{ name }}</span>
</v-col>
<v-col :cols="10">
<v-col :cols="sliderCols || 8">
<v-slider
:value="localValue"
dark
@@ -12,7 +15,8 @@
:max="max"
:min="min"
hide-details
color="#ffd843"
color="accent"
:disabled="disabled"
:step="step"
@start="isClicked = true"
@end="isClicked = false"
@@ -25,6 +29,7 @@
dark
:max="max"
:min="min"
:disabled="disabled"
:value="localValue"
class="mt-0 pt-0"
hide-details
@@ -47,7 +52,7 @@
export default {
name: "Slider",
// eslint-disable-next-line vue/require-prop-types
props: ["min", "max", "name", "value", "step"],
props: ["min", "max", "name", "value", "step", "sliderCols", "disabled"],
data() {
return {
isFocused: false,
@@ -63,7 +68,7 @@ export default {
set(value) {
this.$emit("input", value);
}
}
},
},
methods: {
handleChange(val) {

View File

@@ -1,59 +1,25 @@
<template>
<div>
<v-row
style="width: 400px;"
align="center"
>
<canvas
id="canvasId"
width="800"
height="800"
/>
</v-row>
<v-row
style="width: 400px;"
align="center"
>
<v-simple-table
style="text-align: center;background-color: transparent; display: block;margin: auto"
dense
dark
<v-row>
<v-col
align="center"
cols="12"
>
<template v-slot:default>
<thead>
<tr>
<th class="text-center">
Target
</th>
<th class="text-center">
X
</th>
<th class="text-center">
Y
</th>
<th class="text-center">
Angle
</th>
</tr>
</thead>
<tbody>
<tr
v-for="(target, index) in targets"
:key="index"
>
<td>{{ index }}</td>
<td>{{ target.pose.translation.x.toFixed(2) }}</td>
<td>{{ target.pose.translation.y.toFixed(2) }}</td>
<td>{{ target.pose.rotation.radians.toFixed(2) }}</td>
</tr>
</tbody>
</template>
</v-simple-table>
<span class="text--white">Target Location</span>
<canvas
id="canvasId"
class="mt-2"
width="800"
height="800"
/>
</v-col>
</v-row>
</div>
</template>
<script>
import theme from "../../../theme";
export default {
name: "MiniMap",
props: {
@@ -136,7 +102,7 @@
// so the rect needs to be offset accordingly when drawn
this.ctx.rect(-this.targetWidth / 2, -this.targetHeight / 2, this.targetWidth, this.targetHeight);
this.ctx.fillStyle = "#01a209";
this.ctx.fillStyle = theme.accent;
this.ctx.fill();
// restore the context to its untranslated/unrotated state
@@ -176,7 +142,7 @@
#canvasId {
width: 400px;
height: 400px;
background-color: #2b2b2b;
background-color: #232C37;
border-radius: 5px;
border: 2px solid grey;
box-shadow: 0 0 5px 1px;

View File

@@ -2,27 +2,31 @@
<div>
<v-row align="center">
<v-col
:cols="3"
class=""
cols="10"
md="5"
lg="10"
class="pt-0 pb-0 pl-6"
>
<div style="padding-left:30px">
<CVselect
v-if="isCameraNameEdit === false"
v-model="currentCameraIndex"
name="Camera"
:list="$store.getters.cameraList"
@input="handleInput('currentCamera',currentCameraIndex)"
/>
<CVinput
v-else
v-model="newCameraName"
name="Camera"
:error-message="checkCameraName"
@Enter="saveCameraNameChange"
/>
</div>
<CVselect
v-if="isCameraNameEdit === false"
v-model="currentCameraIndex"
name="Camera"
:list="$store.getters.cameraList"
@input="handleInput('currentCamera',currentCameraIndex)"
/>
<CVinput
v-else
v-model="newCameraName"
name="Camera"
:error-message="checkCameraName"
@Enter="saveCameraNameChange"
/>
</v-col>
<v-col :cols="1">
<v-col
cols="2"
md="1"
lg="2"
>
<CVicon
v-if="isCameraNameEdit === false"
color="#c5c5c5"
@@ -51,8 +55,10 @@
</div>
</v-col>
<v-col
:cols="3"
class=""
cols="10"
md="5"
lg="10"
class="pt-0 pb-0 pl-6"
>
<CVselect
v-model="currentPipelineIndex"
@@ -62,14 +68,12 @@
/>
</v-col>
<v-col
v-if="currentPipelineIndex !== 0"
:cols="1"
class=""
md="3"
cols="2"
md="1"
lg="2"
>
<v-menu
offset-y
dark
auto
>
<template v-slot:activator="{ on }">
@@ -125,14 +129,14 @@
</v-menu>
</v-col>
<v-btn
outlined
color="#ffd843"
@click="handleInput('command','save')"
>
<v-icon>save</v-icon>
Save
</v-btn>
<!-- <v-btn-->
<!-- outlined-->
<!-- color="accent"-->
<!-- @click="handleInput('command','save')"-->
<!-- >-->
<!-- <v-icon>save</v-icon>-->
<!-- Save-->
<!-- </v-btn>-->
</v-row>
<!--pipeline duplicate dialog-->
<v-dialog
@@ -265,15 +269,15 @@
for (let cam in this.cameraList) {
if (this.cameraList.hasOwnProperty(cam)) {
if (this.newCameraName === this.cameraList[cam]) {
return "Camera by that name already exists"
return "A camera by that name already Exists"
}
}
}
} else {
return "Camera name can only contain letters, numbers and spaces"
return "A camera name can only contain letters, numbers and spaces"
}
}
return ""
return "";
},
checkPipelineName() {
if (this.newPipelineName !== this.$store.getters.pipelineList[this.currentPipelineIndex - 1] || this.isPipelineNameEdit === false) {
@@ -286,7 +290,7 @@
}
}
} else {
return "Pipeline name can only contain letters, numbers, and spaces"
return "A pipeline name can only contain letters, numbers, and spaces"
}
}
return ""