Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export default defineComponent({
type: 'CreateTrackAction',
geometryType: 'rectangle',
editableType: true,
selectTrackAfter: false,
selectTrackAfter: 'previousTrack',
},
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ export default defineComponent({
type: 'CreateTrackAction',
geometryType: 'rectangle',
editableType: true,
selectTrackAfter: true,
selectTrackAfter: 'previousTrack',
},
};
}
Expand Down
18 changes: 12 additions & 6 deletions client/dive-common/components/ActionEditors/ActionShortcuts.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
} from 'vue';
import draggable from 'vuedraggable';
import {
DIVEAction, DIVEActionShortcut, TrackSelectAction,
DIVEAction, DIVEActionShortcut, TrackSelectAction, getCreateTrackAfterSelectionLabel,
} from 'dive-common/use/useActions';
import { ButtonShortcut } from 'vue-media-annotator/use/AttributeTypes';
import {
Expand Down Expand Up @@ -188,6 +188,13 @@ export default defineComponent({
updateActionList();
};

const removeAction = (index: number) => {
if (editingShortcut.value) {
editingShortcut.value.actions.splice(index, 1);
updateActionList();
}
};

const saveShortcutDisabled = computed(() => {
if (editingShortcut.value) {
const { description } = editingShortcut.value;
Expand Down Expand Up @@ -217,11 +224,13 @@ export default defineComponent({
updateActionList,
addEditActionindex,
saveAction,
removeAction,
saveShortcutDisabled,
getShortcutDisplay,
hasKeyboardShortcut,
isIconOnlyButton,
onShortcutOrderEnd,
getCreateTrackAfterSelectionLabel,
};
},

Expand Down Expand Up @@ -474,11 +483,8 @@ export default defineComponent({
</div>

<div>
<b class="mr-2">Select Track After:</b><v-icon v-if="item.action.selectTrackAfter" color="success">
mdi-check
</v-icon><v-icon v-else color="error">
mdi-close
</v-icon>
<b class="mr-2">After creation:</b>
<span>{{ getCreateTrackAfterSelectionLabel(item.action.selectTrackAfter) }}</span>
</div>
</v-col>
<v-spacer />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ import {
watch,
} from 'vue';
import { EditAnnotationTypes } from 'vue-media-annotator/layers/';
import { CreateTrackAction } from 'dive-common/use/useActions';
import {
CreateTrackAction,
CREATE_TRACK_AFTER_SELECTION_OPTIONS,
normalizeCreateTrackAfterSelection,
} from 'dive-common/use/useActions';

export default defineComponent({
name: 'CreateTrackActionEditor',
Expand All @@ -17,12 +21,16 @@ export default defineComponent({
emits: ['update:action', 'cancel'],
setup(props, { emit }) {
const geometryTypes: EditAnnotationTypes[] = ['Point', 'rectangle', 'Polygon', 'LineString', 'Time'];
const localAction = ref({ ...props.action });
const editableTypeListEnabled = ref(false);
const editableTypeList: Ref<string> = ref('');
const localAction = ref({
...props.action,
selectTrackAfter: normalizeCreateTrackAfterSelection(props.action.selectTrackAfter),
});
const editableTypeListEnabled = ref(!!props.action.editableTypeList?.length);
const editableTypeList: Ref<string> = ref((props.action.editableTypeList || []).join(', '));
watch(editableTypeList, () => {
localAction.value.editableTypeList = editableTypeList.value.split(',').map((type) => type.trim());
});
const afterSelectionOptions = CREATE_TRACK_AFTER_SELECTION_OPTIONS;
const cancel = () => {
emit('cancel');
};
Expand All @@ -34,6 +42,7 @@ export default defineComponent({
geometryTypes,
editableTypeList,
editableTypeListEnabled,
afterSelectionOptions,
cancel,
save,
};
Expand Down Expand Up @@ -121,12 +130,22 @@ export default defineComponent({
dense
/>

<!-- Select Track After -->
<v-checkbox
<div class="text-subtitle-2 mt-3 mb-1">
After track creation
</div>
<v-radio-group
v-model="localAction.selectTrackAfter"
label="Select Track After"
class="mt-2"
/>
dense
hide-details
class="mt-0"
>
<v-radio
v-for="option in afterSelectionOptions"
:key="option.value"
:label="option.label"
:value="option.value"
/>
</v-radio-group>
</v-card-text>
<v-card-actions>
<v-row dense>
Expand Down
43 changes: 42 additions & 1 deletion client/dive-common/components/CustomUI/CustomUIBase.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import {

import StackedVirtualSidebarContainer from 'dive-common/components/StackedVirtualSidebarContainer.vue';
import CustomUIAttributeValueDisplay from 'dive-common/components/CustomUI/CustomUIAttributeValueDisplay.vue';
import CustomUITrackList from 'dive-common/components/CustomUI/CustomUITrackList.vue';
import CustomUIEditingStatus from 'dive-common/components/CustomUI/CustomUIEditingStatus.vue';
import {
useAttributes, useCameraStore, useConfiguration, useSelectedTrackId, useTime,
useHandler, useTrackStyleManager,
Expand Down Expand Up @@ -77,6 +79,8 @@ export default defineComponent({
StackedVirtualSidebarContainer,
AttributeSubsection,
CustomUIAttributeValueDisplay,
CustomUITrackList,
CustomUIEditingStatus,
},

props: {
Expand All @@ -103,6 +107,19 @@ export default defineComponent({
const title = computed(() => configMan.configuration.value?.customUI?.title || 'Custom Actions');
const information = computed(() => configMan.configuration.value?.customUI?.information || []);
const updatedWidth = computed(() => configMan.configuration.value?.customUI?.width || props.width);
const trackListSettings = computed(() => configMan.configuration.value?.customUI?.trackList);
const trackListEnabled = computed(() => (
trackListSettings.value !== undefined && trackListSettings.value.enabled !== false
));
const showEditingStatus = computed(() => (
trackListEnabled.value && trackListSettings.value?.showEditingStatus !== false
));
const editingStatusTitle = computed(() => (
trackListSettings.value?.editingStatusTitle || 'Current Mode'
));
const trackListAboveActions = computed(() => (
trackListSettings.value?.position === 'above'
));
context.nudgeWidth(updatedWidth.value);
function getAttributeUser({ name, belongs }: { name: string; belongs: 'track' | 'detection' }) {
const attribute = attributes.value.find((attr) => attr.name === name && attr.belongs === belongs);
Expand Down Expand Up @@ -762,6 +779,11 @@ export default defineComponent({
getDisplayValueEntry,
shouldShowDisplayValue,
LONG_VALUE_EXPAND_THRESHOLD,
trackListSettings,
trackListEnabled,
showEditingStatus,
editingStatusTitle,
trackListAboveActions,
};
},
});
Expand All @@ -775,6 +797,14 @@ export default defineComponent({
{{ item }}
</p>
<v-divider />
<template v-if="trackListEnabled && trackListAboveActions">
<CustomUIEditingStatus
v-if="showEditingStatus"
:title="editingStatusTitle"
/>
<CustomUITrackList :settings="trackListSettings" />
<v-divider class="my-2" />
</template>
<v-row v-if="actionButtons.length" dense>
Action Buttons
</v-row>
Expand Down Expand Up @@ -802,10 +832,21 @@ export default defineComponent({
</v-tooltip>
</v-col>
</v-row>
<template v-if="trackListEnabled && !trackListAboveActions">
<v-divider class="my-2" />
<CustomUIEditingStatus
v-if="showEditingStatus"
:title="editingStatusTitle"
/>
<CustomUITrackList :settings="trackListSettings" />
</template>
<v-divider />
<p v-if="attributeButtons.length && selectedTrackIdRef === null">
<p v-if="attributeButtons.length && selectedTrackIdRef === null && !trackListEnabled">
Attribute Action Buttons are disabled because no track is selected
</p>
<p v-else-if="attributeButtons.length && selectedTrackIdRef === null && trackListEnabled">
Select a track from the list above to use attribute buttons
</p>
<p v-else>
Attribute Buttons
</p>
Expand Down
62 changes: 62 additions & 0 deletions client/dive-common/components/CustomUI/CustomUIEditingStatus.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<script lang="ts">
import { defineComponent } from 'vue';
import useEditingStatus from './useEditingStatus';

export default defineComponent({
name: 'CustomUIEditingStatus',
props: {
title: {
type: String,
default: 'Current Mode',
},
},
setup() {
const {
statusHeader,
instructionText,
} = useEditingStatus();

return {
statusHeader,
instructionText,
};
},
});
</script>

<template>
<v-card
outlined
class="custom-ui-editing-status mb-3"
>
<v-card-text class="py-2 px-3">
<div class="custom-ui-editing-status__title text-caption grey--text text--lighten-1 mb-1">
{{ title }}
</div>
<div class="d-flex align-start">
<v-icon
small
class="mr-2 mt-1"
:color="statusHeader.color || undefined"
>
{{ statusHeader.icon }}
</v-icon>
<div>
<div class="custom-ui-editing-status__label text-subtitle-2">
{{ statusHeader.text }}
</div>
<div class="custom-ui-editing-status__instruction text-caption">
{{ instructionText }}
</div>
</div>
</div>
</v-card-text>
</v-card>
</template>

<style scoped lang="scss">
.custom-ui-editing-status__instruction {
line-height: 1.35;
margin-top: 2px;
}
</style>
Loading
Loading