Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create Tools menu #1595

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
185 changes: 107 additions & 78 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -115,15 +115,38 @@
:variant="simplifiedMainMenu ? 'uncontained' : 'round'"
:tooltip="simplifiedMainMenu ? 'Configuration' : undefined"
:width="buttonSize"
:selected="showConfigurationMenu"
:selected="showSubMenu"
class="mb-2"
:style="
interfaceStore.highlightedComponent === 'config-menu-item' && {
animation: 'highlightBackground 0.5s alternate 20',
borderRadius: '10px',
}
"
@click="interfaceStore.mainMenuCurrentStep = 2"
@click="selectSubMenu('config')"
/>
<GlassButton
:label="simplifiedMainMenu ? '' : 'Tools'"
:label-class="[menuLabelSize, '-mb-1']"
icon="mdi-tools"
:icon-size="simplifiedMainMenu ? 25 : undefined"
:icon-class="
interfaceStore.isOnSmallScreen
? 'scale-[100%] -mb-[1px] md:ml-[2px]'
: 'scale-[90%] lg:ml-[1px] -mr-[2px] xl:-mb-[4px]'
"
:variant="simplifiedMainMenu ? 'uncontained' : 'round'"
:tooltip="simplifiedMainMenu ? 'Tools' : undefined"
:width="buttonSize"
:selected="showSubMenu"
class="mb-2"
:style="
interfaceStore.highlightedComponent === 'config-menu-item' && {
animation: 'highlightBackground 0.5s alternate 20',
borderRadius: '10px',
}
"
@click="selectSubMenu('tools')"
/>
<GlassButton
:label="simplifiedMainMenu ? '' : isFullscreen ? 'Exit Fullscreen' : 'Enter Fullscreen'"
Expand Down Expand Up @@ -161,7 +184,7 @@
:tooltip="simplifiedMainMenu ? 'About' : undefined"
:button-class="!simplifiedMainMenu ? '-mt-[5px]' : undefined"
:width="buttonSize"
:selected="showConfigurationMenu"
:selected="showSubMenu"
@click="openAboutDialog"
/>
</div>
Expand All @@ -172,13 +195,13 @@
:class="simplifiedMainMenu ? 'py-0 gap-y-0' : 'py-2 gap-y-1'"
>
<GlassButton
v-for="menuitem in configMenu"
v-for="menuitem in currentSubMenu"
:key="menuitem.title"
:label="interfaceStore.isOnSmallScreen ? undefined : menuitem.title"
:label="simplifiedMainMenu ? undefined : menuitem.title"
:label-class="menuLabelSize"
:button-class="interfaceStore.isOnSmallScreen ? '-ml-[2px]' : ''"
:icon="menuitem.icon"
:selected="currentConfigMenuComponent === menuitem.component"
:selected="interfaceStore.subMenuComponentName === menuitem.title"
variant="uncontained"
:height="buttonSize * 0.45"
:icon-size="buttonSize * 0.5"
Expand All @@ -188,9 +211,9 @@
borderRadius: '4px',
}
"
@click="toggleConfigComponent(menuitem.component)"
@click="toggleSubMenuComponent(menuitem.component)"
><template #content
><div v-if="currentConfigMenuComponent === menuitem.component" class="arrow-left"></div></template
><div v-if="currentSubMenuComponent === menuitem.component" class="arrow-left"></div></template
></GlassButton>
<div class="flex flex-col justify-center align-center">
<v-divider width="70%" class="mb-3" />
Expand All @@ -205,7 +228,7 @@
@click="
() => {
interfaceStore.mainMenuCurrentStep = 1
currentConfigMenuComponent = null
currentSubMenuComponent = null
}
"
/>
Expand All @@ -219,15 +242,15 @@
<teleport to="body">
<GlassModal
:is-visible="
currentConfigMenuComponent !== null &&
currentSubMenuComponent !== null &&
interfaceStore.mainMenuCurrentStep === 2 &&
interfaceStore.isMainMenuVisible
"
position="menuitem"
:class="interfaceStore.isVideoLibraryVisible ? 'opacity-0' : 'opacity-100'"
@close-modal="currentConfigMenuComponent = null"
@close-modal="currentSubMenuComponent = null"
>
<component :is="currentConfigMenuComponent"></component>
<component :is="currentSubMenuComponent"></component>
</GlassModal>
</teleport>

Expand Down Expand Up @@ -348,18 +371,18 @@ import { useSnackbar } from './composables/snackbar'
import { useAppInterfaceStore } from './stores/appInterface'
import { useMainVehicleStore } from './stores/mainVehicle'
import { useWidgetManagerStore } from './stores/widgetManager'
import { ConfigComponent } from './types/general'
import { SubMenuComponent } from './types/general'
import ConfigurationActionsView from './views/ConfigurationActionsView.vue'
import ConfigurationAlertsView from './views/ConfigurationAlertsView.vue'
import ConfigurationDataLakeView from './views/ConfigurationDataLakeView.vue'
import ConfigurationDevelopmentView from './views/ConfigurationDevelopmentView.vue'
import ConfigurationGeneralView from './views/ConfigurationGeneralView.vue'
import ConfigurationJoystickView from './views/ConfigurationJoystickView.vue'
import ConfigurationTelemetryView from './views/ConfigurationLogsView.vue'
import ConfigurationMAVLinkView from './views/ConfigurationMAVLinkView.vue'
import ConfigurationMissionView from './views/ConfigurationMissionView.vue'
import ConfigurationUIView from './views/ConfigurationUIView.vue'
import ConfigurationVideoView from './views/ConfigurationVideoView.vue'
import ToolsDataLakeView from './views/ToolsDataLakeView.vue'
import ToolsMAVLinkView from './views/ToolsMAVLinkView.vue'

const { showDialog, closeDialog } = useInteractionDialog()
const { showSnackbar } = useSnackbar()
Expand All @@ -369,127 +392,138 @@ const vehicleStore = useMainVehicleStore()
const interfaceStore = useAppInterfaceStore()

const showAboutDialog = ref(false)
const showConfigurationMenu = ref(false)
const currentConfigMenuComponent = ref<ConfigComponent>(null)
const showSubMenu = ref(false)
const currentSubMenuName = ref<keyof typeof availableSubMenus | null>(null)
const currentSubMenuComponent = ref<SubMenuComponent>(null)
const mainMenu = ref()

// Main menu
const isMenuOpen = ref(false)
const isSlidingOut = ref(false)
const simplifiedMainMenu = ref(false)
const windowHeight = ref(window.innerHeight)

const { width: windowWidth, height: windowHeight } = useWindowSize()

const configMenu = [
{
icon: 'mdi-view-dashboard-variant',
title: 'General',
component: markRaw(ConfigurationGeneralView) as ConfigComponent,
component: markRaw(ConfigurationGeneralView) as SubMenuComponent,
},
{
icon: 'mdi-monitor-cellphone',
title: 'Interface',
component: markRaw(ConfigurationUIView) as ConfigComponent,
component: markRaw(ConfigurationUIView) as SubMenuComponent,
},
{
icon: 'mdi-controller',
title: 'Joystick',
component: markRaw(ConfigurationJoystickView) as ConfigComponent,
component: markRaw(ConfigurationJoystickView) as SubMenuComponent,
},
{
icon: 'mdi-video',
title: 'Video',
component: markRaw(ConfigurationVideoView) as ConfigComponent,
component: markRaw(ConfigurationVideoView) as SubMenuComponent,
},
{
icon: 'mdi-subtitles-outline',
title: 'Telemetry',
component: markRaw(ConfigurationTelemetryView) as ConfigComponent,
component: markRaw(ConfigurationTelemetryView) as SubMenuComponent,
},
{
icon: 'mdi-alert-rhombus-outline',
title: 'Alerts',
component: markRaw(ConfigurationAlertsView) as ConfigComponent,
component: markRaw(ConfigurationAlertsView) as SubMenuComponent,
},
{
icon: 'mdi-dev-to',
title: 'Dev',
component: markRaw(ConfigurationDevelopmentView) as ConfigComponent,
},
{
icon: 'mdi-protocol',
title: 'MAVLink',
component: markRaw(ConfigurationMAVLinkView) as ConfigComponent,
component: markRaw(ConfigurationDevelopmentView) as SubMenuComponent,
},
{
icon: 'mdi-map-marker-path',
title: 'Mission',
component: markRaw(ConfigurationMissionView) as ConfigComponent,
},
{
icon: 'mdi-database-outline',
title: 'Data-lake',
component: markRaw(ConfigurationDataLakeView) as ConfigComponent,
component: markRaw(ConfigurationMissionView) as SubMenuComponent,
},
{
icon: 'mdi-run-fast',
title: 'Actions',
component: markRaw(ConfigurationActionsView) as ConfigComponent,
component: markRaw(ConfigurationActionsView) as SubMenuComponent,
},
]

const toolsMenu = [
{
icon: 'mdi-protocol',
title: 'MAVLink',
component: markRaw(ToolsMAVLinkView) as SubMenuComponent,
},
{
icon: 'mdi-database-outline',
title: 'Data-lake',
component: markRaw(ToolsDataLakeView) as SubMenuComponent,
},
]

const availableSubMenus = {
config: configMenu,
tools: toolsMenu,
}

const currentSubMenu = computed(() => {
if (currentSubMenuName.value === null) return []
return availableSubMenus[currentSubMenuName.value]
})

watch(
() => interfaceStore.configComponent,
(component) => {
if (component < 0) {
currentConfigMenuComponent.value = null
return
}
currentConfigMenuComponent.value = configMenu[component].component
() => interfaceStore.subMenuComponentName,
(subMenuComponentName) => {
currentSubMenuComponent.value =
currentSubMenu.value.find((item) => item.title === subMenuComponentName)?.component || null
}
)

const toggleConfigComponent = (component: ConfigComponent): void => {
if (currentConfigMenuComponent.value === null) {
currentConfigMenuComponent.value = component
const selectSubMenu = (subMenuName: keyof typeof availableSubMenus): void => {
currentSubMenuName.value = subMenuName
interfaceStore.mainMenuCurrentStep = 2
}

const toggleSubMenuComponent = (component: SubMenuComponent): void => {
if (currentSubMenuComponent.value === null) {
currentSubMenuComponent.value = component
interfaceStore.configModalVisibility = true
return
}
if (currentConfigMenuComponent.value === component) {
currentConfigMenuComponent.value = null
if (currentSubMenuComponent.value === component) {
currentSubMenuComponent.value = null
interfaceStore.configModalVisibility = false
return
}
currentConfigMenuComponent.value = component
currentSubMenuComponent.value = component
interfaceStore.configModalVisibility = true
}

const isConfigModalVisible = computed(() => interfaceStore.isConfigModalVisible)

watch(isConfigModalVisible, (newVal) => {
if (newVal === false) {
currentConfigMenuComponent.value = null
currentSubMenuComponent.value = null
}
})

watch(
() => windowHeight.value < 450,
(isSmall: boolean) => {
simplifiedMainMenu.value = isSmall
}
)

const updateWindowHeight = (): void => {
windowHeight.value = window.innerHeight
}
const topBottomBarScale = computed(() => {
return windowWidth.value / originalBarWidth
})

onMounted(() => {
window.addEventListener('resize', updateWindowHeight)
if (windowHeight.value < 450) {
simplifiedMainMenu.value = true
}
const maxScreenHeightPixelsThatFitsLargeMenu = computed(() => {
const heightTopBar = widgetStore.currentTopBarHeightPixels * topBottomBarScale.value
const heightBottomBar = widgetStore.currentBottomBarHeightPixels * topBottomBarScale.value
const visibleAreaHeight = windowHeight.value - heightTopBar - heightBottomBar
return visibleAreaHeight
})

onBeforeUnmount(() => {
window.removeEventListener('resize', updateWindowHeight)
const simplifiedMainMenu = computed(() => {
const threshold = windowWidth.value > 1300 ? 860 : 680
return maxScreenHeightPixelsThatFitsLargeMenu.value < threshold
})

const mainMenuWidth = computed(() => {
Expand Down Expand Up @@ -556,7 +590,7 @@ const closeMainMenu = (): void => {
isSlidingOut.value = false
isMenuOpen.value = false
interfaceStore.mainMenuCurrentStep = 1
currentConfigMenuComponent.value = null
currentSubMenuComponent.value = null
}, 20)
}

Expand Down Expand Up @@ -638,14 +672,13 @@ const menuLabelSize = computed(() => {
return 'text-[10px]'
})

const mainMenu = ref()
onClickOutside(mainMenu, () => {
if (interfaceStore.mainMenuCurrentStep === 1 && !interfaceStore.isTutorialVisible) {
closeMainMenu()
}
if (
interfaceStore.mainMenuCurrentStep === 2 &&
currentConfigMenuComponent.value === null &&
currentSubMenuComponent.value === null &&
!interfaceStore.isTutorialVisible
) {
closeMainMenu()
Expand Down Expand Up @@ -680,23 +713,19 @@ const fullScreenToggleIcon = computed(() => (isFullscreen.value ? 'mdi-fullscree

const currentSelectedViewName = computed(() => widgetStore.currentView.name)

const { width: windowWidth } = useWindowSize()

const originalBarWidth = 1800

const topBarScaleStyle = computed(() => {
const scale = windowWidth.value / originalBarWidth
return {
transform: `scale(${scale})`,
transform: `scale(${topBottomBarScale.value})`,
transformOrigin: 'top left',
width: `${originalBarWidth}px`,
}
})

const bottomBarScaleStyle = computed(() => {
const scale = windowWidth.value / originalBarWidth
return {
transform: `scale(${scale})`,
transform: `scale(${topBottomBarScale.value})`,
transformOrigin: 'bottom left',
width: `${originalBarWidth}px`,
}
Expand Down
Loading