Skip to content
Draft
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
110 changes: 109 additions & 1 deletion client/dive-common/components/AnnotationVisibilityMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,17 @@ export default defineComponent({
type: Boolean,
default: true,
},
additionalPointSettings: {
type: Object as PropType<{ showLabels: boolean; sizePercent: number }>,
default: () => ({ showLabels: true, sizePercent: 100 }),
},
},
emits: ['set-annotation-state', 'update:tail-settings', 'update:show-user-created-icon'],
emits: [
'set-annotation-state',
'update:tail-settings',
'update:show-user-created-icon',
'update:additional-point-settings',
],
setup(props, { emit }) {
const STORAGE_KEY = 'annotationVisibilityMenu.expanded';

Expand Down Expand Up @@ -96,6 +105,14 @@ export default defineComponent({
description: 'Head Tail',
click: () => toggleVisible('LineString'),
},
{
id: 'additionalPoints',
type: 'additionalPoints',
active: isVisible('additionalPoints'),
icon: 'mdi-vector-point',
description: 'Additional Points',
click: () => toggleVisible('additionalPoints'),
},
{
id: 'text',
type: 'text',
Expand Down Expand Up @@ -124,6 +141,21 @@ export default defineComponent({
emit('update:show-user-created-icon', !props.showUserCreatedIcon);
};

const toggleAdditionalPointShowLabels = () => {
emit('update:additional-point-settings', {
...props.additionalPointSettings,
showLabels: !props.additionalPointSettings.showLabels,
});
};

const updateAdditionalPointSize = (event: Event) => {
const value = Number.parseInt((event.target as HTMLInputElement).value, 10);
emit('update:additional-point-settings', {
...props.additionalPointSettings,
sizePercent: value,
});
};

return {
isExpanded,
viewButtons,
Expand All @@ -132,6 +164,8 @@ export default defineComponent({
toggleExpanded,
updateTailSettings,
toggleShowUserCreatedIcon,
toggleAdditionalPointShowLabels,
updateAdditionalPointSize,
};
},
});
Expand Down Expand Up @@ -195,6 +229,36 @@ export default defineComponent({
/>
</v-list-item-content>
</v-list-item>
<v-list-item v-if="isVisible('additionalPoints')">
<v-list-item-content>
<v-card
class="pa-4 flex-column d-flex"
outlined
flat
>
<v-checkbox
:input-value="additionalPointSettings.showLabels"
label="Show point labels"
dense
hide-details
class="mt-0"
@click.stop
@change="toggleAdditionalPointShowLabels"
/>
<div class="py-2" />
<label for="additional-point-size-menu">Point size: {{ additionalPointSettings.sizePercent }}%</label>
<input
id="additional-point-size-menu"
type="range"
class="tail-slider-width"
min="50"
max="200"
:value="additionalPointSettings.sizePercent"
@input="updateAdditionalPointSize($event)"
>
</v-card>
</v-list-item-content>
</v-list-item>
<v-list-item>
<v-list-item-icon>
<v-btn
Expand Down Expand Up @@ -302,6 +366,50 @@ export default defineComponent({
/>
</v-card>
</v-menu>
<v-menu
v-else-if="button.id === 'additionalPoints'"
:key="`${button.id}-view`"
open-on-hover
bottom
offset-y
:close-on-content-click="false"
>
<template #activator="{ on, attrs }">
<v-btn
v-bind="attrs"
:color="button.active ? 'grey darken-2' : ''"
class="mx-1 mode-button"
small
v-on="on"
@click="button.click"
>
<v-icon>{{ button.icon }}</v-icon>
</v-btn>
</template>
<v-card
class="pa-4 flex-column d-flex"
outlined
>
<v-checkbox
:input-value="additionalPointSettings.showLabels"
label="Show point labels"
dense
hide-details
@change="toggleAdditionalPointShowLabels"
/>
<div class="py-2" />
<label for="additional-point-size-expanded">Point size: {{ additionalPointSettings.sizePercent }}%</label>
<input
id="additional-point-size-expanded"
type="range"
class="tail-slider-width"
min="50"
max="200"
:value="additionalPointSettings.sizePercent"
@input="updateAdditionalPointSize($event)"
>
</v-card>
</v-menu>
<v-btn
v-else
:key="`${button.id}-view-button`"
Expand Down
2 changes: 1 addition & 1 deletion client/dive-common/components/DeleteControls.vue
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export default Vue.extend({
point {{ selectedFeatureHandle }}
</span>
<span v-else-if="editingMode">
{{ editingMode }}
{{ editingMode === 'additionalPoints' ? 'point' : editingMode }}
</span>
<span v-else>unselected</span>
<v-icon
Expand Down
148 changes: 145 additions & 3 deletions client/dive-common/components/EditorMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import {
computed,
defineComponent,
nextTick,
PropType,
ref,
watch,
Expand Down Expand Up @@ -66,8 +67,26 @@ export default defineComponent({
type: Boolean,
default: true,
},
additionalPointSettings: {
type: Object as PropType<{ showLabels: boolean; sizePercent: number }>,
default: () => ({ showLabels: true, sizePercent: 100 }),
},
selectedKey: {
type: String,
default: '',
},
/** All additionalPoints keys seen on any track at the current frame (current camera). */
allAdditionalPointKeys: {
type: Array as PropType<string[]>,
default: () => [],
},
},
emits: ['set-annotation-state', 'update:tail-settings', 'update:show-user-created-icon'],
emits: [
'set-annotation-state',
'update:tail-settings',
'update:show-user-created-icon',
'update:additional-point-settings',
],
setup(props, { emit }) {
const toolTimeTimeout = ref<number | null>(null);
const STORAGE_KEY = 'editorMenu.editButtonsExpanded';
Expand All @@ -90,14 +109,20 @@ export default defineComponent({
rectangle: 'Drag to draw rectangle. Press ESC to exit.',
Polygon: 'Click to place vertices. Right click to close.',
LineString: 'Click to place head/tail points.',
additionalPoints: 'Click to place a named point inside the selected bounding box.',
},
Editing: {
rectangle: 'Drag vertices to resize the rectangle',
Polygon: 'Drag midpoints to create new vertices. Click vertices to select for deletion.',
LineString: 'Click endpoints to select for deletion.',
additionalPoints: 'Drag to move the named point. Delete to remove the current point name.',
},
};

const additionalPointName = ref(props.selectedKey || '');
/** v-combobox @change runs when v-model is set programmatically; skip spurious commits (e.g. "New Point"). */
const suppressAdditionalPointCommit = ref(false);

const editButtons = computed((): ButtonData[] => {
const em = props.editingMode;
return [
Expand Down Expand Up @@ -131,6 +156,31 @@ export default defineComponent({
...r.mousetrap(),
],
})),
{
id: 'additionalPoints',
icon: 'mdi-vector-point',
active: props.editingTrack && em === 'additionalPoints',
description: 'Additional Points',
mousetrap: [{
bind: '4',
handler: () => {
const key = additionalPointName.value.trim()
|| props.selectedKey
|| (props.allAdditionalPointKeys && props.allAdditionalPointKeys[0])
|| 'point';
additionalPointName.value = key;
emit('set-annotation-state', { editing: 'additionalPoints', key });
},
}],
click: () => {
const key = additionalPointName.value.trim()
|| props.selectedKey
|| (props.allAdditionalPointKeys && props.allAdditionalPointKeys[0])
|| 'point';
additionalPointName.value = key;
emit('set-annotation-state', { editing: 'additionalPoints', key });
},
},
];
});

Expand Down Expand Up @@ -184,6 +234,66 @@ export default defineComponent({
}
});

watch(() => props.selectedKey, (val) => {
if (val && val !== additionalPointName.value) {
additionalPointName.value = val;
}
});

const commitAdditionalPointName = () => {
if (suppressAdditionalPointCommit.value) {
return;
}
const key = additionalPointName.value.trim();
if (!key) {
return;
}
additionalPointName.value = key;
if (
props.editingMode === 'additionalPoints'
&& key === (props.selectedKey || '').trim()
) {
return;
}
emit('set-annotation-state', { editing: 'additionalPoints', key });
};

const additionalPointNameOptions = computed(() => {
const options = new Set<string>(props.allAdditionalPointKeys || []);
const selected = props.selectedKey?.trim();
if (selected) {
options.add(selected);
}
const cur = typeof additionalPointName.value === 'string'
? additionalPointName.value.trim()
: '';
if (cur) {
options.add(cur);
}
return Array.from(options).sort((a, b) => a.localeCompare(b));
});

const createNewPointName = () => {
const existing = new Set(additionalPointNameOptions.value);
let index = 1;
let candidate = `point-${index}`;
while (existing.has(candidate)) {
index += 1;
candidate = `point-${index}`;
}
suppressAdditionalPointCommit.value = true;
// Emit first so parent `selectedKey` updates before any combobox @change runs.
emit('set-annotation-state', {
editing: 'additionalPoints',
key: candidate,
skipAdditionalPointRename: true,
});
additionalPointName.value = candidate;
nextTick(() => {
suppressAdditionalPointCommit.value = false;
});
};

return {
modeToolTips,
editButtons,
Expand All @@ -194,6 +304,10 @@ export default defineComponent({
toggleEditButtonsExpanded,
activeEditButton,
editButtonsMenuKey,
additionalPointName,
commitAdditionalPointName,
additionalPointNameOptions,
createNewPointName,
};
},
});
Expand Down Expand Up @@ -272,7 +386,7 @@ export default defineComponent({
>
<v-list-item-icon>
<v-btn
:disabled="!editingMode"
:disabled="!editingMode || (button.id === 'additionalPoints' && editingDetails === 'disabled')"
:outlined="!button.active"
:color="button.active ? editingHeader.color : ''"
class="mx-1"
Expand Down Expand Up @@ -311,7 +425,7 @@ export default defineComponent({
<v-btn
v-for="button in editButtons"
:key="button.id + 'view'"
:disabled="!editingMode"
:disabled="!editingMode || (button.id === 'additionalPoints' && editingDetails === 'disabled')"
:outlined="!button.active"
:color="button.active ? editingHeader.color : ''"
class="mx-1"
Expand All @@ -322,6 +436,32 @@ export default defineComponent({
<v-icon>{{ button.icon }}</v-icon>
</v-btn>
</template>
<v-combobox
v-if="editingTrack && editingMode === 'additionalPoints'"
v-model="additionalPointName"
class="ml-2"
style="max-width: 220px;"
:items="additionalPointNameOptions"
dense
hide-details
outlined
label="Point name"
@change="commitAdditionalPointName"
@blur="commitAdditionalPointName"
@keydown.enter.prevent="commitAdditionalPointName"
/>
<v-btn
v-if="editingTrack && editingMode === 'additionalPoints'"
class="ml-2"
color="success"
small
@click="createNewPointName"
>
<v-icon small class="mr-1">
mdi-plus
</v-icon>
Point
</v-btn>
<slot name="delete-controls" />
<v-spacer />
<slot name="multicam-controls" />
Expand All @@ -330,9 +470,11 @@ export default defineComponent({
:visible-modes="visibleModes"
:tail-settings="tailSettings"
:show-user-created-icon="showUserCreatedIcon"
:additional-point-settings="additionalPointSettings"
@set-annotation-state="$emit('set-annotation-state', $event)"
@update:tail-settings="$emit('update:tail-settings', $event)"
@update:show-user-created-icon="$emit('update:show-user-created-icon', $event)"
@update:additional-point-settings="$emit('update:additional-point-settings', $event)"
/>
</div>
</v-row>
Expand Down
Loading
Loading