Skip to content

Commit

Permalink
Components: Very-generic-input-widget: Add component
Browse files Browse the repository at this point in the history
Signed-off-by: Arturo Manzoli <[email protected]>
  • Loading branch information
ArturoManzoli committed Nov 1, 2024
1 parent 6ac295c commit b2af60a
Show file tree
Hide file tree
Showing 20 changed files with 2,835 additions and 44 deletions.
94 changes: 94 additions & 0 deletions src/assets/defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { DistanceDisplayUnit } from '@/libs/units'
import {
type MiniWidgetProfile,
type Profile,
CustomWidgetManagerVars,
CustomWidgetType,
MiniWidgetManagerVars,
MiniWidgetType,
WidgetManagerVars,
Expand All @@ -29,6 +31,7 @@ export const defaultWidgetManagerVars: WidgetManagerVars = {
lastNonMaximizedWidth: 0.2,
lastNonMaximizedHeight: 0.36,
highlighted: false,
disableResponsiveness: false,
}

export const defaultMiniWidgetManagerVars: MiniWidgetManagerVars = {
Expand All @@ -37,6 +40,97 @@ export const defaultMiniWidgetManagerVars: MiniWidgetManagerVars = {
highlighted: false,
}

export const defaultCustomWidgetManagerVars: CustomWidgetManagerVars = {
everMounted: false,
configMenuOpen: false,
highlighted: false,
customWidgetVars: CustomWidgetType.Button,
cockpitActions: [],
}

export const defaultCustomWidgetContainers = [
{
name: '0-left',
elements: [],
},
{
name: '1-left',
elements: [],
},
{
name: '2-left',
elements: [],
},
{
name: '3-left',
elements: [],
},
{
name: '4-left',
elements: [],
},
{
name: '5-left',
elements: [],
},
{
name: '6-left',
elements: [],
},
{
name: '7-left',
elements: [],
},
{
name: '8-left',
elements: [],
},
{
name: '9-left',
elements: [],
},
{
name: '0-right',
elements: [],
},
{
name: '1-right',
elements: [],
},
{
name: '2-right',
elements: [],
},
{
name: '3-right',
elements: [],
},
{
name: '4-right',
elements: [],
},
{
name: '5-right',
elements: [],
},
{
name: '6-right',
elements: [],
},
{
name: '7-right',
elements: [],
},
{
name: '8-right',
elements: [],
},
{
name: '9-right',
elements: [],
},
]

const hostname = window.location.hostname
export const defaultBlueOsAddress = 'http://blueos-avahi.local'
export const defaultGlobalAddress = !hostname || hostname == 'localhost' ? defaultBlueOsAddress : hostname
Expand Down
Binary file added src/assets/widgets/CustomWidgetBase.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
142 changes: 119 additions & 23 deletions src/components/EditMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@
</div>
<v-divider class="opacity-20" />
<div
class="flex flex-row justify-start relative items-center bg-[#CBCBCB2A] elevation-5 2xl:h-full xl:h-[45px] h-[35px] overflow-hidden"
class="flex flex-row max-h-[48px] justify-start relative items-center bg-[#CBCBCB2A] elevation-5 2xl:h-full xl:h-[45px] h-[35px] overflow-hidden"
>
<v-icon
size="sm"
Expand Down Expand Up @@ -444,7 +444,7 @@
<div class="flex items-center justify-between edit-panel bottom-panel" :class="{ active: editMode }">
<div class="w-px h-full bg-[#FFFFFF18]" />
<div
class="flex flex-col justify-between items-center 2xl:w-[30%] w-[25%] max-w-[240px] h-full text-white 2xl:pr-2 px-1 2xl:py-5 xl:py-4 lg:py-1"
class="flex flex-col justify-around items-center 2xl:w-[30%] w-[25%] max-w-[240px] h-full text-white 2xl:pr-2 px-1 2xl:py-5 xl:py-4 lg:py-1"
>
<div>
<p class="2xl:text-md text-xs ml-1">Widget type:</p>
Expand All @@ -453,7 +453,7 @@
theme="dark"
variant="filled"
density="compact"
:items="['Regular', 'Mini']"
:items="['Regular', 'Mini', 'Input']"
class="bg-[#27384255] 2xl:scale-100 scale-[80%]"
hide-details
@change="widgetMode = $event"
Expand All @@ -463,17 +463,18 @@
<div v-show="widgetMode === 'Regular'" class="w-[90%] 2xl:text-[16px] text-xs text-center mt-6">
To be placed on the main view area
</div>
<div
v-show="widgetMode === 'Regular widgets'"
class="2xl:text-md text-sm mt-3 2xl:px-3 px-2 bg-[#3B78A8] rounded-lg"
>
Click or drag to add
</div>
<div v-show="widgetMode === 'Regular'" class="text-xs mt-3 2xl:px-3 px-2 rounded-lg">(Drag card to add)</div>
<div v-show="widgetMode === 'Mini'" class="w-[90%] 2xl:text-[16px] text-xs text-center mt-6">
To be placed on the top and bottom bars
</div>
<div v-show="widgetMode === 'Mini'" class="2xl:text-md text-sm mt-3 2xl:px-3 px-2 rounded-lg">
(Drag card in place to add)
<div v-show="widgetMode === 'Mini'" class="text-xs mt-3 2xl:px-3 px-2 rounded-lg">(Drag card to add)</div>
<div v-show="widgetMode === 'Input'">
<v-btn
type="flat"
class="bg-[#FFFFFF33] text-white w-[95%]"
@click="store.addWidget(WidgetType.CustomWidgetBase, store.currentView)"
>Add widget base
</v-btn>
</div>
</div>
</div>
Expand All @@ -491,7 +492,7 @@
@dragstart="onRegularWidgetDragStart"
@dragend="onRegularWidgetDragEnd(widgetType)"
>
<v-tooltip text="Click or drag to add" location="top" theme="light">
<v-tooltip text="Drag to add" location="top" theme="light">
<template #activator="{ props: tooltipProps }">
<div />
<img
Expand All @@ -504,8 +505,7 @@
class="flex items-center justify-center w-full p-1 transition-all bg-[#3B78A8] rounded-b-md text-white"
>
<span class="whitespace-normal text-center">{{
widgetType.replace(/([a-z])([A-Z])/g, '$1 $2').replace(/^./, (str) => str.toUpperCase()) ||
'Very Generic Indicator'
widgetType.replace(/([a-z])([A-Z])/g, '$1 $2').replace(/^./, (str) => str.toUpperCase())
}}</span>
</div>
</template>
Expand All @@ -522,19 +522,47 @@
id="mini-widget-card"
:ref="(el) => (miniWidgetContainers[miniWidget.component] = el as HTMLElement)"
:key="miniWidget.hash"
class="flex flex-col items-center justify-between w-full rounded-md bg-[#273842] hover:brightness-125 h-[90%] aspect-square cursor-pointer elevation-4 overflow-clip pointer-events-none"
class="flex flex-col items-center w-full justify-between rounded-md bg-[#273842] hover:brightness-125 h-[90%] aspect-square cursor-pointer elevation-4 overflow-clip"
:draggable="false"
>
<div />
<div id="draggable-mini-widget" class="m-2 pointer-events-auto select-auto cursor-grab" :draggable="true">
<div class="flex justify-center pointer-events-none min-w-[160px]">
<div class="flex justify-center pointer-events-none min-w-[170px]">
<MiniWidgetInstantiator :mini-widget="miniWidget" />
</div>
</div>
<div
class="flex items-center justify-center w-full py-1 px-2 transition-all bg-[#3B78A8] rounded-b-md text-white"
>
<span class="whitespace-normal text-center">{{
miniWidget.name.replace(/([a-z])([A-Z])/g, '$1 $2').replace(/^./, (str) => str.toUpperCase())
}}</span>
</div>
</div>
</div>
<div
v-show="widgetMode === 'Input'"
ref="availableCustomWidgetElementsContainer"
class="flex items-center w-full h-full gap-3 overflow-auto pr-2"
>
<div
v-for="miniWidget in availableCustomWidgetElementsTypes"
id="mini-widget-card"
:key="miniWidget.hash"
class="flex flex-col items-center w-full justify-between rounded-md bg-[#273842] hover:brightness-125 h-[90%] aspect-square cursor-pointer elevation-4 overflow-clip"
draggable="false"
>
<div />
<div id="draggable-mini-widget" class="m-2 pointer-events-auto select-auto cursor-grab" draggable="true">
<div class="flex justify-center pointer-events-none min-w-[170px]">
<MiniWidgetInstantiator :mini-widget="miniWidget" />
</div>
</div>
<div class="flex items-center justify-center w-full p-1 transition-all bg-[#3B78A8] rounded-b-md text-white">
<div
class="flex items-center justify-center w-full py-1 px-2 transition-all bg-[#3B78A8] rounded-b-md text-white"
>
<span class="whitespace-normal text-center">{{
miniWidget.name.replace(/([a-z])([A-Z])/g, '$1 $2').replace(/^./, (str) => str.toUpperCase()) ||
'Very Generic Indicator'
miniWidget.name.replace(/([a-z])([A-Z])/g, '$1 $2').replace(/^./, (str) => str.toUpperCase())
}}</span>
</div>
</div>
Expand Down Expand Up @@ -587,6 +615,21 @@
</v-card>
</GlassModal>
</teleport>
<transition
enter-active-class="transition-transform duration-500 ease-in-out"
leave-active-class="transition-transform duration-0 ease-in-out"
enter-from-class="translate-x-full opacity-0"
enter-to-class="translate-x-0 opacity-100"
leave-from-class="translate-x-0 opacity-100"
leave-to-class="translate-x-full opacity-0"
>
<div
v-if="store.isElementsPropsDrawerVisible && store.editingMode && store.elementToShowOnDrawer"
class="flex fixed w-[250px] h-[78vh] right-0 top-0 border-l-[1px] border-[#FFFFFF44] text-white elevation-5 bg-[#051e2d]"
>
<ElementConfigPanel />
</div>
</transition>
</template>

<script setup lang="ts">
Expand All @@ -596,28 +639,52 @@ import { computed, onMounted, ref, toRefs, watch } from 'vue'
import { nextTick } from 'vue'
import { type UseDraggableOptions, useDraggable, VueDraggable } from 'vue-draggable-plus'
import { defaultMiniWidgetManagerVars } from '@/assets/defaults'
import { defaultCustomWidgetManagerVars, defaultMiniWidgetManagerVars } from '@/assets/defaults'
/* @ts-ignore */
import BoatThumb from '@/assets/vehicles/BlueBoat_thumb.png'
/* @ts-ignore */
import BlueRoboticsLogo from '@/assets/vehicles/BlueRoboticsLogo.png'
/* @ts-ignore */
import RovThumb from '@/assets/vehicles/BlueROV_thumb.png'
/* @ts-ignore */
import AttitudeImg from '@/assets/widgets/Attitude.png'
/* @ts-ignore */
import CompassImg from '@/assets/widgets/Compass.png'
/* @ts-ignore */
import CompassHUDImg from '@/assets/widgets/CompassHUD.png'
/* @ts-ignore */
import CustomWidgetBaseImg from '@/assets/widgets/CustomWidgetBase.png'
/* @ts-ignore */
import DepthHUDImg from '@/assets/widgets/DepthHUD.png'
/* @ts-ignore */
import IFrameImg from '@/assets/widgets/IFrame.png'
/* @ts-ignore */
import ImageViewImg from '@/assets/widgets/ImageView.png'
/* @ts-ignore */
import MapImg from '@/assets/widgets/Map.png'
/* @ts-ignore */
import MiniWidgetsBarImg from '@/assets/widgets/MiniWidgetsBar.png'
/* @ts-ignore */
import URLVideoPlayerImg from '@/assets/widgets/URLVideoPlayer.png'
/* @ts-ignore */
import VideoPlayerImg from '@/assets/widgets/VideoPlayer.png'
/* @ts-ignore */
import VirtualHorizonImg from '@/assets/widgets/VirtualHorizon.png'
import { useInteractionDialog } from '@/composables/interactionDialog'
import { MavType } from '@/libs/connection/m2r/messages/mavlink2rest-enum'
import { isHorizontalScroll } from '@/libs/utils'
import { useAppInterfaceStore } from '@/stores/appInterface'
import { useWidgetManagerStore } from '@/stores/widgetManager'
import { type Profile, type View, type Widget, MiniWidgetType, WidgetType } from '@/types/widgets'
import {
type Profile,
type View,
type Widget,
CustomWidgetElementType,
MiniWidgetType,
WidgetType,
} from '@/types/widgets'
import ElementConfigPanel from './ElementConfigPanel.vue'
import ExpansiblePanel from './ExpansiblePanel.vue'
import GlassModal from './GlassModal.vue'
import MiniWidgetInstantiator from './MiniWidgetInstantiator.vue'
Expand Down Expand Up @@ -670,11 +737,23 @@ const availableMiniWidgetTypes = computed(() =>
}))
)
const availableCustomWidgetElementsTypes = computed(() =>
Object.values(CustomWidgetElementType).map((widgetType) => ({
component: widgetType,
name: widgetType,
options: {},
hash: uuid(),
isBoolean: false,
managerVars: defaultCustomWidgetManagerVars,
cockpitActions: [],
}))
)
const widgetImages = {
Attitude: AttitudeImg,
Compass: CompassImg,
DepthHUD: DepthHUDImg,
CompassHUD: CompassHUDImg,
CustomWidgetBase: CustomWidgetBaseImg,
DepthHUD: DepthHUDImg,
IFrame: IFrameImg,
ImageView: ImageViewImg,
Map: MapImg,
Expand Down Expand Up @@ -851,6 +930,7 @@ const resetSavedProfiles = (): void => {
const availableWidgetsContainer = ref()
const availableMiniWidgetsContainer = ref()
const availableCustomWidgetElementsContainer = ref()
// @ts-ignore: Documentation is not clear on what generic should be passed to 'UseDraggableOptions'
const miniWidgetsContainerOptions = ref<UseDraggableOptions>({
Expand All @@ -860,8 +940,24 @@ const miniWidgetsContainerOptions = ref<UseDraggableOptions>({
})
useDraggable(availableMiniWidgetsContainer, availableMiniWidgetTypes, miniWidgetsContainerOptions)
// @ts-ignore: Documentation is not clear on what generic should be passed to 'UseDraggableOptions'
const customWidgetElementContainerOptions = ref<UseDraggableOptions>({
animation: '150',
group: widgetAddMenuGroupOptions,
sort: false,
})
useDraggable(
availableCustomWidgetElementsContainer,
availableCustomWidgetElementsTypes,
customWidgetElementContainerOptions
)
onMounted(() => {
const widgetContainers = [availableWidgetsContainer.value, availableMiniWidgetsContainer.value]
const widgetContainers = [
availableWidgetsContainer.value,
availableMiniWidgetsContainer.value,
availableCustomWidgetElementsContainer.value,
]
widgetContainers.forEach((container) => {
container.addEventListener(
'wheel',
Expand Down
Loading

0 comments on commit b2af60a

Please sign in to comment.