2023-08-21 01:51:35 -04:00
< script setup lang = "ts" >
import type { Component } from "vue" ;
2025-05-06 18:21:41 -04:00
import { computed , ref } from "vue" ;
2023-08-21 01:51:35 -04:00
import { useCameraSettingsStore } from "@/stores/settings/CameraSettingsStore" ;
import { useStateStore } from "@/stores/StateStore" ;
import InputTab from "@/components/dashboard/tabs/InputTab.vue" ;
import ThresholdTab from "@/components/dashboard/tabs/ThresholdTab.vue" ;
import ContoursTab from "@/components/dashboard/tabs/ContoursTab.vue" ;
import AprilTagTab from "@/components/dashboard/tabs/AprilTagTab.vue" ;
import ArucoTab from "@/components/dashboard/tabs/ArucoTab.vue" ;
2024-01-15 22:28:34 -05:00
import ObjectDetectionTab from "@/components/dashboard/tabs/ObjectDetectionTab.vue" ;
2023-08-21 01:51:35 -04:00
import OutputTab from "@/components/dashboard/tabs/OutputTab.vue" ;
import TargetsTab from "@/components/dashboard/tabs/TargetsTab.vue" ;
import PnPTab from "@/components/dashboard/tabs/PnPTab.vue" ;
import Map3DTab from "@/components/dashboard/tabs/Map3DTab.vue" ;
import { WebsocketPipelineType } from "@/types/WebsocketDataTypes" ;
2025-05-06 18:21:41 -04:00
import { useDisplay } from "vuetify/lib/composables/display" ;
2023-08-21 01:51:35 -04:00
interface ConfigOption {
2023-08-31 16:56:58 -04:00
tabName : string ;
component : Component ;
2023-08-21 01:51:35 -04:00
}
const allTabs = Object . freeze ( {
inputTab : {
tabName : "Input" ,
component : InputTab
} ,
thresholdTab : {
tabName : "Threshold" ,
component : ThresholdTab
} ,
contoursTab : {
tabName : "Contours" ,
component : ContoursTab
} ,
apriltagTab : {
tabName : "AprilTag" ,
component : AprilTagTab
} ,
arucoTab : {
tabName : "Aruco" ,
component : ArucoTab
} ,
2024-01-15 22:28:34 -05:00
objectDetectionTab : {
tabName : "Object Detection" ,
component : ObjectDetectionTab
} ,
2023-08-21 01:51:35 -04:00
outputTab : {
tabName : "Output" ,
component : OutputTab
} ,
targetsTab : {
tabName : "Targets" ,
component : TargetsTab
} ,
pnpTab : {
tabName : "PnP" ,
component : PnPTab
} ,
map3dTab : {
tabName : "3D" ,
component : Map3DTab
}
} ) ;
const selectedTabs = ref ( [ 0 , 0 , 0 , 0 ] ) ;
2025-05-06 18:21:41 -04:00
const { smAndDown , mdAndDown , lgAndDown , xl } = useDisplay ( ) ;
2023-08-21 01:51:35 -04:00
2025-05-06 18:21:41 -04:00
const getTabGroups = ( ) : ConfigOption [ ] [ ] => {
if ( smAndDown . value || useCameraSettingsStore ( ) . isDriverMode ) {
2023-08-21 01:51:35 -04:00
return [ Object . values ( allTabs ) ] ;
2025-05-06 18:21:41 -04:00
} else if ( mdAndDown . value || ! useStateStore ( ) . sidebarFolded ) {
2023-08-21 01:51:35 -04:00
return [
2023-08-31 16:56:58 -04:00
[
allTabs . inputTab ,
allTabs . thresholdTab ,
allTabs . contoursTab ,
allTabs . apriltagTab ,
allTabs . arucoTab ,
2024-01-15 22:28:34 -05:00
allTabs . objectDetectionTab ,
2023-08-31 16:56:58 -04:00
allTabs . outputTab
] ,
[ allTabs . targetsTab , allTabs . pnpTab , allTabs . map3dTab ]
2023-08-21 01:51:35 -04:00
] ;
2025-05-06 18:21:41 -04:00
} else if ( lgAndDown . value ) {
2023-08-21 01:51:35 -04:00
return [
2023-08-31 16:56:58 -04:00
[ allTabs . inputTab ] ,
2024-01-15 22:28:34 -05:00
[
allTabs . thresholdTab ,
allTabs . contoursTab ,
allTabs . apriltagTab ,
allTabs . arucoTab ,
allTabs . objectDetectionTab ,
allTabs . outputTab
] ,
2023-08-31 16:56:58 -04:00
[ allTabs . targetsTab , allTabs . pnpTab , allTabs . map3dTab ]
2023-08-21 01:51:35 -04:00
] ;
2025-05-06 18:21:41 -04:00
} else if ( xl . value ) {
2023-08-21 01:51:35 -04:00
return [
[ allTabs . inputTab ] ,
[ allTabs . thresholdTab ] ,
2024-01-15 22:28:34 -05:00
[ allTabs . contoursTab , allTabs . apriltagTab , allTabs . arucoTab , allTabs . objectDetectionTab , allTabs . outputTab ] ,
2023-08-21 01:51:35 -04:00
[ allTabs . targetsTab , allTabs . pnpTab , allTabs . map3dTab ]
] ;
}
return [ ] ;
} ;
const tabGroups = computed < ConfigOption [ ] [ ] > ( ( ) => {
// Just return the input tab because we know that is always the case in driver mode
2023-08-31 16:56:58 -04:00
if ( useCameraSettingsStore ( ) . isDriverMode ) return [ [ allTabs . inputTab ] ] ;
2023-08-21 01:51:35 -04:00
const allow3d = useCameraSettingsStore ( ) . currentPipelineSettings . solvePNPEnabled ;
const isAprilTag = useCameraSettingsStore ( ) . currentWebsocketPipelineType === WebsocketPipelineType . AprilTag ;
const isAruco = useCameraSettingsStore ( ) . currentWebsocketPipelineType === WebsocketPipelineType . Aruco ;
2024-01-15 22:28:34 -05:00
const isObjectDetection =
useCameraSettingsStore ( ) . currentWebsocketPipelineType === WebsocketPipelineType . ObjectDetection ;
2023-08-21 01:51:35 -04:00
2023-10-15 15:11:23 -04:00
return getTabGroups ( )
. map ( ( tabGroup ) =>
tabGroup . filter (
( tabConfig ) =>
! ( ! allow3d && tabConfig . tabName === "3D" ) && //Filter out 3D tab any time 3D isn't calibrated
2024-01-15 22:28:34 -05:00
! ( ( ! allow3d || isAprilTag || isAruco || isObjectDetection ) && tabConfig . tabName === "PnP" ) && //Filter out the PnP config tab if 3D isn't available, or we're doing AprilTags
! ( ( isAprilTag || isAruco || isObjectDetection ) && tabConfig . tabName === "Threshold" ) && //Filter out threshold tab if we're doing AprilTags
! ( ( isAprilTag || isAruco || isObjectDetection ) && tabConfig . tabName === "Contours" ) && //Filter out contours if we're doing AprilTags
2023-10-15 15:11:23 -04:00
! ( ! isAprilTag && tabConfig . tabName === "AprilTag" ) && //Filter out apriltag unless we actually are doing AprilTags
2024-01-15 22:28:34 -05:00
! ( ! isAruco && tabConfig . tabName === "Aruco" ) &&
! ( ! isObjectDetection && tabConfig . tabName === "Object Detection" ) //Filter out aruco unless we actually are doing Aruco
2023-10-15 15:11:23 -04:00
)
2023-08-31 16:56:58 -04:00
)
2023-10-15 15:11:23 -04:00
. filter ( ( it ) => it . length ) ; // Remove empty tab groups
2023-08-21 01:51:35 -04:00
} ) ;
2025-05-06 18:21:41 -04:00
const onBeforeTabUpdate = ( ) => {
2023-08-21 01:51:35 -04:00
// Force the current tab to the input tab on driver mode change
2023-08-31 16:56:58 -04:00
if ( useCameraSettingsStore ( ) . isDriverMode ) {
2023-08-21 01:51:35 -04:00
selectedTabs . value [ 0 ] = 0 ;
}
2025-05-06 18:21:41 -04:00
} ;
2023-08-21 01:51:35 -04:00
< / script >
< template >
2023-08-31 16:56:58 -04:00
< v-row no -gutters class = "tabGroups" >
2025-01-01 03:04:20 -05:00
< template v-if = "!useCameraSettingsStore().hasConnected" >
2025-01-07 08:45:39 -05:00
< v-col cols = "12" >
2025-01-01 03:04:20 -05:00
< v-card color = "error" >
2025-05-06 18:21:41 -04:00
< v-card-title class = "text-white" >
2025-01-01 03:04:20 -05:00
Camera has not connected . Please check your connection and try again .
< / v-card-title >
< / v-card >
< / v-col >
< / template >
< template v-else >
< v-col
v - for = "(tabGroupData, tabGroupIndex) in tabGroups"
: key = "tabGroupIndex"
2025-05-06 18:21:41 -04:00
: cols = "tabGroupIndex == 1 && useCameraSettingsStore().currentPipelineSettings.doMultiTarget ? 7 : ''"
2025-01-01 03:04:20 -05:00
: class = "tabGroupIndex !== tabGroups.length - 1 && 'pr-3'"
2025-05-06 18:21:41 -04:00
@ vue : before - update = "onBeforeTabUpdate"
2025-01-01 03:04:20 -05:00
>
< v-card color = "primary" height = "100%" class = "pr-4 pl-4" >
2025-05-06 18:21:41 -04:00
< v-tabs v-model = "selectedTabs[tabGroupIndex]" grow bg-color="primary" height="48" slider-color="accent" >
2025-01-01 03:04:20 -05:00
< v-tab v-for = "(tabConfig, index) in tabGroupData" :key="index" >
{ { tabConfig . tabName } }
< / v-tab >
< / v-tabs >
2025-01-07 08:45:39 -05:00
< div class = "pl-2 pr-2 pt-3 pb-3" >
2025-01-01 03:04:20 -05:00
< KeepAlive >
< Component :is = "tabGroupData[selectedTabs[tabGroupIndex]].component" / >
< / KeepAlive >
< / div >
< / v-card >
< / v-col >
< / template >
2023-08-21 01:51:35 -04:00
< / v-row >
< / template >
< style >
2023-08-31 16:56:58 -04:00
. v - slide - group _ _next -- disabled ,
. v - slide - group _ _prev -- disabled {
2023-08-21 01:51:35 -04:00
display : none ! important ;
}
< / style >