Skip to content
Merged
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
66 changes: 32 additions & 34 deletions client/dive-common/components/ControlsContainer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {
Controls,
injectAggregateController,
Timeline,
TimelineKey,
} from 'vue-media-annotator/components';
import { TimelineDisplay, UISettingsKey } from 'vue-media-annotator/ConfigurationManager';
import TimelineCharts from 'vue-media-annotator/components/controls/TimelineCharts.vue';
Expand All @@ -24,7 +23,6 @@ export default defineComponent({
Controls,
FileNameTimeDisplay,
Timeline,
TimelineKey,
TimelineButtons,
TimelineCharts,
},
Expand Down Expand Up @@ -57,6 +55,9 @@ export default defineComponent({
const attributesFilter = useAttributesFilters();
const { enabledTimelines: enabledFilterTimelines } = useTimelineFilters();
const getUISetting = (key: UISettingsKey) => (configMan.getUISetting(key));
const isUISettingExplicitlyTrue = (key: UISettingsKey) => (
configMan.getFlatUISettingMap()[key] === true
);
if (getUISetting('UIDetections') === false && getUISetting('UIEvents')) {
currentView.value = 'Events';
}
Expand All @@ -80,12 +81,20 @@ export default defineComponent({
currentView.value = timelines[0].name;
}
}
const enabledKey = ref(false);
const enabledKey = ref(isUISettingExplicitlyTrue('UILegendForceOpen'));
const chartAreaLeftInset = ref(0);
const chartAreaRightInset = ref(0);
const dismissedButtons: Ref<string[]> = ref([]); // buttons that have been dismissed from the timelineConfig;
const dismissedHeights: Ref<{name: string; height: number}[]> = ref([]);
const {
attributeSwimlaneData,
} = useAttributesFilters();

const showLegendToggle = computed(() => (
getUISetting('UILegendControls')
&& !isUISettingExplicitlyTrue('UILegendHideToggle')
));

const toggleLegendKey = () => {
enabledKey.value = !enabledKey.value;
};

const timelineHeight = computed(() => {
const activeConfig = configMan.getActiveTimelineConfig();
Expand Down Expand Up @@ -144,19 +153,11 @@ export default defineComponent({
maxFrame, frame, seek, volume, setVolume, setSpeed, speed,
} = injectAggregateController().value;

// Timeline Key Sizing and Refs
const timelineRef: Ref<typeof Timeline & {$el: HTMLElement; clientHeight: number} | null> = ref(null);
const controlsRef: Ref<typeof Controls & {$el: HTMLElement} | null> = ref(null);
const keyHeight = computed(() => ((timelineRef.value !== null) ? timelineRef.value.clientHeight : 0));
const keyTop = computed(() => ((controlsRef.value !== null) ? controlsRef.value.$el.clientHeight : 0));
const keyWidth = ref(0);
watch(() => timelineRef.value && timelineRef.value.$el.clientWidth, () => {
keyWidth.value = timelineRef.value?.$el.clientWidth || 0;
});
const updateSizes = () => {
keyWidth.value = timelineRef.value?.$el.clientWidth || 0;
// retained for Timeline @resize handler
};
const swimlaneOffset = ref(0);

const addDismissedButton = ({ name, height }: {name: string; height: number}) => {
dismissedButtons.value.push(name);
Expand All @@ -173,6 +174,11 @@ export default defineComponent({
}
};

const onChartAreaInsets = ({ leftInset, rightInset }: { leftInset: number; rightInset: number }) => {
chartAreaLeftInset.value = leftInset;
chartAreaRightInset.value = rightInset;
};

watch(timelineHeight, () => {
emit('timeline-height', timelineHeight.value);
});
Expand All @@ -190,21 +196,19 @@ export default defineComponent({
ticks,
getUISetting,
timelineDisabled,
// Timeline Ref
controlsRef,
timelineRef,
keyHeight,
keyTop,
keyWidth,
enabledKey,
updateSizes,
swimlaneOffset,
//Timeline Config
showLegendToggle,
toggleLegendKey,
timelineHeight,
attributeSwimlaneData,
dismissedButtons,
addDismissedButton,
removeDismissedButton,
chartAreaLeftInset,
chartAreaRightInset,
onChartAreaInsets,
};
},
});
Expand Down Expand Up @@ -238,7 +242,7 @@ export default defineComponent({
<span>Collapse/Expand Timeline</span>
</v-tooltip>
<v-tooltip
v-if="getUISetting('UILegendControls')"
v-if="showLegendToggle"
open-delay="200"
bottom
>
Expand All @@ -248,7 +252,7 @@ export default defineComponent({
:color="enabledKey ? 'primary' : ''"
class="ml-2"
v-on="on"
@click="enabledKey = !enabledKey"
@click="toggleLegendKey"
>
mdi-key
</v-icon>
Expand Down Expand Up @@ -367,6 +371,8 @@ export default defineComponent({
:frame="frame"
:display="!collapsed"
:timeline-height="timelineHeight"
:key-inset="chartAreaLeftInset"
:chart-right-inset="chartAreaRightInset"
@seek="seek"
@resize="updateSizes"
>
Expand All @@ -386,6 +392,7 @@ export default defineComponent({
:group-chart-data="groupChartData"
:current-view="currentView"
:collapsed="collapsed"
:show-key="enabledKey"
:start-frame="startFrame"
:end-frame="endFrame"
:child-max-frame="childMaxFrame"
Expand All @@ -395,19 +402,10 @@ export default defineComponent({
:dismissed-buttons="dismissedButtons"
@select-track="$emit('select-track', $event)"
@dismiss="addDismissedButton($event)"
@chart-area-insets="onChartAreaInsets"
/>
</template>
</Timeline>
<timeline-key
v-if="enabledKey"
:current-view="currentView"
:client-height="keyHeight"
:client-top="keyTop"
:client-width="keyWidth"
:offset="swimlaneOffset"
:dismissed-buttons="dismissedButtons"
:data="attributeSwimlaneData[currentView]"
/>
</v-col>
</template>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ export default defineComponent({
},
setup() {
const configMan = useConfiguration();
const UILegendControls = ref(configMan.getUISetting('UILegendControls') as boolean);
const UITimelineSelection = ref(configMan.getUISetting('UITimelineSelection') as boolean);
const UIPlaybackControls = ref(configMan.getUISetting('UIPlaybackControls') as boolean);
const UIAudioControls = ref(configMan.getUISetting('UIAudioControls') as boolean);
Expand All @@ -21,10 +20,12 @@ export default defineComponent({
const UILockCamera = ref(configMan.getUISetting('UILockCamera') as boolean);
const UIResetCamera = ref(configMan.getUISetting('UIResetCamera') as boolean);

watch([UILegendControls, UITimelineSelection, UIPlaybackControls, UIAudioControls,
UITimeDisplay, UIFrameDisplay, UIImageNameDisplay, UILockCamera, UISpeedControls, UIResetCamera], () => {
watch([
UITimelineSelection, UIPlaybackControls,
UIAudioControls, UITimeDisplay, UIFrameDisplay, UIImageNameDisplay, UILockCamera, UISpeedControls,
UIResetCamera,
], () => {
const data = {
UILegendControls: UILegendControls.value ? undefined : false,
UITimelineSelection: UITimelineSelection.value ? undefined : false,
UIPlaybackControls: UIPlaybackControls.value ? undefined : false,
UIAudioControls: UIAudioControls.value ? undefined : false,
Expand All @@ -38,7 +39,6 @@ export default defineComponent({
configMan.setUISettings('UIControls', data);
});
return {
UILegendControls,
UITimelineSelection,
UIPlaybackControls,
UIAudioControls,
Expand All @@ -59,12 +59,6 @@ export default defineComponent({
<v-card-title>Playback Controls</v-card-title>
<v-card-text>
<div>
<v-row dense>
<v-switch
v-model="UILegendControls"
label="Legend Controls"
/>
</v-row>
<v-row dense>
<v-switch
v-model="UITimelineSelection"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,101 @@
import {
defineComponent, ref, watch,
} from 'vue';
import {
KEY_PANEL_MAX_WIDTH,
KEY_PANEL_MIN_WIDTH,
} from 'vue-media-annotator/components/controls/timelineLayout';
import migrateLegendSettingsUISettings from 'vue-media-annotator/components/controls/migrateLegendSettings';
import { useConfiguration } from 'vue-media-annotator/provides';

function readNumberSetting(
flatMap: Record<string, unknown>,
key: 'UILegendKeyMinWidth' | 'UILegendKeyMaxWidth',
fallback: number,
): number {
const value = flatMap[key];
return typeof value === 'number' && Number.isFinite(value) ? value : fallback;
}

const KEY_WIDTH_INPUT_MIN = 50;

function parseKeyWidth(value: number, fallback: number): number {
return Number.isFinite(value) ? Math.max(KEY_WIDTH_INPUT_MIN, Math.round(value)) : fallback;
}

export default defineComponent({
name: 'UITimeline',
components: {
},
setup() {
const configMan = useConfiguration();
if (configMan.configuration.value?.UISettings) {
configMan.configuration.value.UISettings = migrateLegendSettingsUISettings(
configMan.configuration.value.UISettings,
) || configMan.configuration.value.UISettings;
}
const timelineSettings = configMan.getUISettingValue('UITimeline');
const timelineMap = typeof timelineSettings === 'object' && timelineSettings
? timelineSettings as Record<string, unknown>
: {};
const UIDetections = ref(configMan.getUISetting('UIDetections') as boolean);
const UIEvents = ref(configMan.getUISetting('UIEvents') as boolean);
const UILegendControls = ref(configMan.getUISetting('UILegendControls') as boolean);
const UILegendForceOpen = ref(timelineMap.UILegendForceOpen === true);
const UILegendHideToggle = ref(timelineMap.UILegendHideToggle === true);
const UILegendKeyMinWidth = ref(readNumberSetting(timelineMap, 'UILegendKeyMinWidth', KEY_PANEL_MIN_WIDTH));
const UILegendKeyMaxWidth = ref(readNumberSetting(timelineMap, 'UILegendKeyMaxWidth', KEY_PANEL_MAX_WIDTH));

const saveTimelineSettings = () => {
const minWidth = parseKeyWidth(UILegendKeyMinWidth.value, KEY_PANEL_MIN_WIDTH);
const maxWidth = Math.max(
minWidth,
parseKeyWidth(UILegendKeyMaxWidth.value, KEY_PANEL_MAX_WIDTH),
);

watch([UIDetections, UIEvents], () => {
const data = {
UIDetections: UIDetections.value ? undefined : false,
UIEvents: UIEvents.value ? undefined : false,

UILegendControls: UILegendControls.value ? undefined : false,
UILegendForceOpen: UILegendForceOpen.value ? true : undefined,
UILegendHideToggle: UILegendHideToggle.value ? true : undefined,
UILegendKeyMinWidth: minWidth !== KEY_PANEL_MIN_WIDTH ? minWidth : undefined,
UILegendKeyMaxWidth: maxWidth !== KEY_PANEL_MAX_WIDTH ? maxWidth : undefined,
};
configMan.setUISettings('UITimeline', data);
});
};

watch([
UIDetections,
UIEvents,
UILegendControls,
UILegendForceOpen,
UILegendHideToggle,
], saveTimelineSettings);

const normalizeKeyWidthInputs = () => {
const minWidth = parseKeyWidth(UILegendKeyMinWidth.value, KEY_PANEL_MIN_WIDTH);
const maxWidth = Math.max(
minWidth,
parseKeyWidth(UILegendKeyMaxWidth.value, KEY_PANEL_MAX_WIDTH),
);
UILegendKeyMinWidth.value = minWidth;
UILegendKeyMaxWidth.value = maxWidth;
saveTimelineSettings();
};

return {
UIDetections,
UIEvents,
UILegendControls,
UILegendForceOpen,
UILegendHideToggle,
UILegendKeyMinWidth,
UILegendKeyMaxWidth,
KEY_PANEL_MIN_WIDTH,
KEY_PANEL_MAX_WIDTH,
KEY_WIDTH_INPUT_MIN,
normalizeKeyWidthInputs,
};
},

Expand All @@ -47,6 +120,56 @@ export default defineComponent({
label="Events Timeline"
/>
</v-row>
<v-divider class="my-3" />
<div class="text-subtitle-2 mb-2">
Legend / Key
</div>
<v-row dense>
<v-switch
v-model="UILegendControls"
label="Legend Controls"
/>
</v-row>
<v-row dense>
<v-switch
v-model="UILegendForceOpen"
label="Legend Force Open"
hint="Show the timeline legend/key when the UI launches (users can still close it unless Hide Toggle is enabled)"
persistent-hint
/>
</v-row>
<v-row dense>
<v-switch
v-model="UILegendHideToggle"
label="Legend Hide Toggle"
hint="Hide the legend toggle button to prevent users from closing the legend (often used with Force Open)"
persistent-hint
/>
</v-row>
<v-row dense>
<v-col cols="6">
<v-text-field
v-model.number="UILegendKeyMinWidth"
type="number"
:min="KEY_WIDTH_INPUT_MIN"
label="Key Min Width (px)"
:hint="`Default: ${KEY_PANEL_MIN_WIDTH}px (minimum: ${KEY_WIDTH_INPUT_MIN}px)`"
persistent-hint
@blur="normalizeKeyWidthInputs"
/>
</v-col>
<v-col cols="6">
<v-text-field
v-model.number="UILegendKeyMaxWidth"
type="number"
:min="KEY_WIDTH_INPUT_MIN"
label="Key Max Width (px)"
:hint="`Default: ${KEY_PANEL_MAX_WIDTH}px (minimum: ${KEY_WIDTH_INPUT_MIN}px)`"
persistent-hint
@blur="normalizeKeyWidthInputs"
/>
</v-col>
</v-row>
</div>
</v-card-text>
</v-card>
Expand Down
2 changes: 1 addition & 1 deletion client/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "dive-dsa",
"version": "1.11.40",
"version": "1.11.41",
"author": {
"name": "Kitware, Inc.",
"email": "Bryon.Lewis@kitware.com"
Expand Down
Loading
Loading